home *** CD-ROM | disk | FTP | other *** search
/ Developer CD Series 1994 June: Reference Library / Dev.CD Jun 94.toast / Periodicals / develop / develop Issue 15 / develop 15 code / 3D Interface / Demo3D / U3DDrawing.cp < prev    next >
Encoding:
Text File  |  1993-06-02  |  116.4 KB  |  4,048 lines  |  [TEXT/MPS ]

  1. /*
  2.     File:        U3DDrawing.cp
  3.  
  4.     Contains:    Adorners, classes, etc for 3D drawing effects
  5.  
  6.     Written by:    Jamie Osborne, Robin Mair, Faulkner White, Henri Lamiraux
  7.  
  8.     Copyright:    © 1992-1993 by Apple Computer, Inc.
  9.  
  10. */
  11.  
  12. /*
  13.     Some notes:
  14.             1.  This code makes your controls non-internationalized.  If you wish
  15.                 to make the controls draw with the correct system orientation
  16.                 (e.g. right to left for Hebrew), you need to check the gEnvironment
  17.                 variable and setup your drawing rects correctly.  The next Develop
  18.                 CD should have a version of this code with 
  19.                 internationalization supported.
  20.             2.  This code IS compatible with non-Color Quickdraw machines.
  21.             3.    On slower machines (anything slower than an '030), this code will
  22.                 be slow.  You should take this into account if you use this library
  23.                 in your application.  Test it out on a slower machine to see if
  24.                 it is still fast enough for your needs.  If it IS too slow, there
  25.                 are many opportunities in the code for optimization.  One example
  26.                 is removing some of the CGraphicsState objects from some of the
  27.                 routines and replacing them with CPenNormal();
  28.             4.  If you have any questions about the code, please direct them to 
  29.                 Jamie Osborne (AppleLink: JWO; Internet: jwo@applelink.apple.com).
  30. */
  31.  
  32. #ifndef __QUICKDRAW__
  33.     #include <Quickdraw.h>
  34. #endif
  35.  
  36. #ifndef __RESOURCES__
  37.     #include <Resources.h>
  38. #endif
  39.  
  40. #ifndef __GESTALTEQU__
  41.     #include <GestaltEqu.h>
  42. #endif
  43.  
  44. #include "U3DDrawing.h"
  45.  
  46. //--------------------------------------------------------------------------------------
  47. // InitU3DDrawing        Include this routine in your initialization function
  48. //--------------------------------------------------------------------------------------
  49.  
  50. #pragma segment AInit
  51. pascal void InitU3DDrawing()
  52. {
  53.     macroDontDeadStrip(TGrayBackgroundAdorner);
  54.     macroDontDeadStrip(TWhiteBackgroundAdorner);
  55.     macroDontDeadStrip(T3DGrayBackgroundAdorner);
  56.     macroDontDeadStrip(T3DFrameAdorner);
  57.     macroDontDeadStrip(T3DLineTopAdorner);
  58.     macroDontDeadStrip(T3DLineBottomAdorner);
  59.     macroDontDeadStrip(T3DLineRightAdorner);
  60.     macroDontDeadStrip(T3DLineLeftAdorner);
  61.  
  62.     macroDontDeadStrip(T3DCheckBox);
  63.     macroDontDeadStrip(T3DRadio);
  64.     macroDontDeadStrip(T3DButton);
  65.     
  66.     macroDontDeadStrip(T3DIconAdorner);
  67.     macroDontDeadStrip(TIconSuite);
  68.     macroDontDeadStrip(T3DIconButton);
  69. }
  70.  
  71. //==================================================================================== 
  72. //    •••••••••••••••••••••••••••• 3D Utility Classes •••••••••••••••••••••••••••••••••••
  73. //==================================================================================== 
  74.  
  75. //======================================================================================
  76. //    CLASS: CGraphicsState
  77. //======================================================================================
  78. //
  79. //        This class is used to save and restore the current Quickdraw graphics state.
  80. //    Create one of these objects at the beginning of a drawing method then use it to
  81. //    save and restore the state of the graphics before and after your drawing.  When
  82. //    one of these objects is created the Constructor saves off the current settings
  83. // for the fore and background colors, the pen state and the current textstyle.  It
  84. //    also does a PenNormal() call in preparation for drawing.  The destructor will just
  85. // reverse this process.  Two methods are provided that allow an explicit Save() and
  86. //    Restore() that mimic the constructor and destructor.  These method can be called 
  87. // if you want to reuse the same object during drawing.  The destructor will use the
  88. //    last values saved.
  89.  
  90. //--------------------------------------------------------------------------------------
  91. // CGraphicsState::CGraphicsState        ---<<• CONSTRUCTOR •>>---
  92. //--------------------------------------------------------------------------------------
  93. //
  94. //        Initialize the instance variables of the object by saving the current state
  95. // of some of the current port settings.
  96. //
  97. #pragma segment AUtils
  98.  
  99. CGraphicsState::CGraphicsState ()
  100. {
  101.      // • First save off the foreground and background colors and the penstate
  102.     GetIfColor ( fSaveForeColor );
  103.     GetIfBkColor ( fSaveBackColor );
  104.     GetPenState ( fSavePenState );    
  105.     CPenNormal ();
  106.     
  107.     // • Now save off the current port's textstyle information
  108.     GetPortTextStyle ( fSaveTextStyle );
  109.     
  110. } // CGraphicsState::CGraphicsState
  111.  
  112. //--------------------------------------------------------------------------------------
  113. // CGraphicsState::~CGraphicsState        ---<<• DESTRUCTOR •>>---
  114. //--------------------------------------------------------------------------------------
  115. //
  116. //        The destructor simply restores the last Save() state when it is called
  117. //
  118. #pragma segment AUtils
  119.  
  120. CGraphicsState::~CGraphicsState ()
  121. {
  122.     // • Restore the foreground and background colors and the penstate
  123.     SetIfColor ( fSaveForeColor );
  124.     SetIfBkColor ( fSaveBackColor );
  125.     SetPenState ( fSavePenState );
  126.  
  127.     // • Now restore the textstyle of the current port
  128.     SetPortTextStyle ( fSaveTextStyle );
  129.     
  130. } // CGraphicsState::~CGraphicsState
  131.  
  132. //--------------------------------------------------------------------------------------
  133. // CGraphicsState::Save
  134. //--------------------------------------------------------------------------------------
  135. //
  136. //        Save off the current graphics state so that we can restore it again
  137. // after we are done with our drawing.  Also calls PenNormal () to set the
  138. //    pen to the Quickdraw defaults.
  139. //
  140. #pragma segment AUtils
  141.  
  142. void CGraphicsState::Save ()
  143. {
  144.      // • First save off the foreground and background colors and the penstate
  145.     GetIfColor ( fSaveForeColor );
  146.     GetIfBkColor ( fSaveBackColor );
  147.     GetPenState ( fSavePenState );    
  148.     CPenNormal ();
  149.     
  150.     // • Now save off the current port's textstyle information
  151.     GetPortTextStyle ( fSaveTextStyle );
  152.     
  153. } // CGraphicsState::Save
  154.  
  155. //--------------------------------------------------------------------------------------
  156. // CGraphicsState::Restore
  157. //--------------------------------------------------------------------------------------
  158. //
  159. //        Restores the graphics state, this is typically called after doing some drawing
  160. // and after we have created an instance of this class or called the Save () method.
  161. //
  162. #pragma segment AUtils
  163.     
  164. void CGraphicsState::Restore ()
  165. {
  166.  
  167.     // • Restore the foreground and background colors and the penstate
  168.     SetIfColor ( fSaveForeColor );
  169.     SetIfBkColor ( fSaveBackColor );
  170.     SetPenState ( fSavePenState );
  171.  
  172.     // • Now restore the textstyle of the current port
  173.     SetPortTextStyle ( fSaveTextStyle );
  174.     
  175. } // CGraphicsState::Restore
  176.  
  177.  
  178. //======================================================================================
  179. // Class CDrawPerDevice
  180. //======================================================================================
  181. //    
  182.  
  183. //--------------------------------------------------------------------------------------
  184. // CDrawPerDevice::CDrawPerDevice        ---<<• CONSTRUCTOR •>>---
  185. //--------------------------------------------------------------------------------------
  186. #pragma segment AUtils
  187.  
  188. CDrawPerDevice::CDrawPerDevice()
  189. {
  190.     //    • Initialize our instance variables
  191.     fSaveClip = NULL;
  192.     fGDHandle = NULL;
  193.     
  194. } // CDrawPerDevice::CDrawPerDevice
  195.  
  196. //--------------------------------------------------------------------------------------
  197. // CDrawPerDevice::CDrawPerDevice        ---<<• CONSTRUCTOR •>>---
  198. //--------------------------------------------------------------------------------------
  199. #pragma segment AUtils
  200.  
  201. CDrawPerDevice::CDrawPerDevice ( const CRect& area )
  202. {
  203.  
  204.     //    • Initialize our fields
  205.     fSaveClip = NULL;
  206.     fGDHandle = NULL;
  207.     
  208.     //    • Save off the area passed in and convert it to global coordinates
  209.     fGlobalArea = area;
  210.     LocalToGlobal ( fGlobalArea[topLeft] );
  211.     LocalToGlobal ( fGlobalArea[botRight] );
  212.     
  213.     
  214. //    Remember the View port info
  215.     fFocus.itsViewPortInfo.clip = MakeNewRgn();
  216.     GetFocus(fFocus);
  217.     
  218.     fSaveClip = fFocus.itsViewPortInfo.clip;
  219.  
  220. //    Set a placeholder for non Color QD drawing
  221.     fDoneOldQD = FALSE;
  222. } // CDrawPerDevice::CDrawPerDevice
  223.  
  224. //--------------------------------------------------------------------------------------
  225. // CDrawPerDevice::~CDrawPerDevice        ---<<• DESTRUCTOR •>>---
  226. //--------------------------------------------------------------------------------------
  227. #pragma segment AUtils
  228.  
  229. CDrawPerDevice::~CDrawPerDevice()
  230. {
  231. //    Restore the port information
  232.     SetFocus(fFocus);
  233.  
  234. //    • If we have a saved clip then make sure that we displose of the region
  235.     fFocus.itsViewPortInfo.clip = DisposeIfRgnHandle(fFocus.itsViewPortInfo.clip);    
  236.     
  237. } // CDrawPerDevice::~CDrawPerDevice
  238.  
  239. //--------------------------------------------------------------------------------------
  240. // CDrawPerDevice::SetDrawingArea
  241. //--------------------------------------------------------------------------------------
  242. //
  243. //        This does the same thing as the constructor and can be used to reset the drawing
  244. //    area at anytime
  245. //
  246. #pragma segment AUtils
  247.  
  248. pascal void CDrawPerDevice::SetDrawingArea ( const CRect& area )
  249. {
  250.     //    • Save off the area passed in and convert it to global coordinates
  251.     fGlobalArea = area;
  252.     LocalToGlobal ( fGlobalArea[topLeft] );
  253.     LocalToGlobal ( fGlobalArea[botRight] );
  254.  
  255.     //    • Get a handle to the first device in the device list
  256.     fGDHandle = GetDeviceList ();
  257.  
  258. //    Remember the View port info
  259.     fFocus.itsViewPortInfo.clip = MakeNewRgn();
  260.     GetFocus(fFocus);
  261.  
  262.     fSaveClip = fFocus.itsViewPortInfo.clip;
  263.  
  264. } // CDrawPerDevice::SetDrawingArea
  265.  
  266. //--------------------------------------------------------------------------------------
  267. // CDrawPerDevice::NextDevice
  268. //--------------------------------------------------------------------------------------
  269. //
  270. //        This is the method that is called during the drawing process.  What it does is 
  271. //    cycle through each of the devices in the device list, returning the pixel size for
  272. //    the device, it also sets the clipping to the portion of the drawing area that is 
  273. // in need of drawing on the current device
  274.  
  275. #pragma segment AUtils
  276.  
  277. pascal Boolean CDrawPerDevice::NextDevice ( short& pixelSize )
  278. {
  279.     
  280.     Boolean foundActiveScreen = FALSE;
  281.     CRect    bounds;
  282.     CRect area;
  283.     
  284. //    Go ye not into this code if ye have not Color Quickdraw
  285.     if (!gConfiguration.hasColorQD)
  286.     {
  287.         pixelSize = 1;
  288.         foundActiveScreen = !fDoneOldQD;
  289.         fDoneOldQD = !fDoneOldQD;
  290.         return foundActiveScreen;
  291.     }
  292.     
  293.     //    • We will iterate over the device list while there are devices.  As we do this
  294.     //    are returning the pixel size of the current device and setting the clipping to
  295.     //    the area of that device that is in need of redrawing
  296.  
  297.   if (fGDHandle == NULL)
  298.     fGDHandle = GetDeviceList();
  299.   else
  300.     fGDHandle = GetNextDevice(fGDHandle);
  301.  
  302.     while ((fGDHandle != NULL) && (foundActiveScreen == FALSE))
  303.            if (TestDeviceAttribute(fGDHandle, screenDevice) && 
  304.                TestDeviceAttribute(fGDHandle, screenActive)) 
  305.         {
  306.             foundActiveScreen = TRUE;
  307.             pixelSize = (*(*fGDHandle)->gdPMap)->pixelSize;
  308.  
  309.             //    • Get the bounds of the current device
  310.             bounds = (*fGDHandle)->gdRect;
  311.             if ( SectRect ( bounds, fGlobalArea, area ) ) 
  312.             {
  313.                 //    • Convert the overlapping area to local coordinates
  314.                 GlobalToLocal ( area[topLeft] );
  315.                 GlobalToLocal ( area[botRight] );
  316.                 
  317.                 //    • Create a temporary region and convert the overlapped area to a region
  318.                 CTemporaryRegion    tempRgn;
  319.                 RectRgn ( tempRgn, area );
  320.                 
  321.                 //    • Set the temporary region to the intersection between the area and the
  322.                 // saved clipping region
  323.                 SectRgn ( tempRgn, fSaveClip, tempRgn );
  324.                 //  Clip to the visregion,too
  325.                 SectRgn(tempRgn, qd.thePort->visRgn, tempRgn);
  326.                 
  327.                 //    • Set the clip to the overlap
  328.                 SetClip ( tempRgn );
  329.                 
  330.             }
  331.             else
  332.             {
  333.                 foundActiveScreen = FALSE;
  334.                 fGDHandle = GetNextDevice(fGDHandle);
  335.             }
  336.         }
  337.         else
  338.             fGDHandle = GetNextDevice(fGDHandle);
  339.  
  340.   return foundActiveScreen;
  341.  
  342. } // CDrawPerDevice::NextDevice
  343.  
  344.  
  345. //======================================================================================
  346. // CPenNormal    - a color version of PenNormal()
  347. //======================================================================================
  348. #pragma segment AUtils
  349.  
  350. pascal void CPenNormal()
  351. {
  352.     RGBForeColor(gRGBBlack);
  353.     RGBBackColor(gRGBWhite);
  354.     PenNormal();
  355.  
  356. } // CPenNormal
  357.  
  358.  
  359.  
  360. //==================================================================================== 
  361. //    •••••••••••••••••••••••••••• 3D TView Adorners •••••••••••••••••••••••••••••••••••
  362. //==================================================================================== 
  363.  
  364. //--------------------------------------------------------------------------------------------------
  365. #pragma segment A3DOpen
  366.  
  367. pascal void TWhiteBackgroundAdorner::Initialize()
  368. {
  369.     inherited::Initialize();
  370. }
  371.  
  372.  
  373. //--------------------------------------------------------------------------------------------------
  374. #pragma segment A3DOpen
  375.  
  376. pascal void TWhiteBackgroundAdorner::IWhiteBackgroundAdorner(Boolean freeOnDeletion)
  377. {
  378.  
  379.     this->IAdorner(kWhiteBackgroundAdorner,freeOnDeletion);
  380.  
  381. } // T3DWhiteBackgroundAdorner::I3DWhiteBackgroundAdorner
  382.  
  383.  
  384. //--------------------------------------------------------------------------------------------------
  385. #pragma segment A3DRes
  386.  
  387. pascal void TWhiteBackgroundAdorner::Draw(TView* itsView, const VRect& area)
  388. {
  389.  
  390.     CRect            qdArea;
  391.     short            pixelSize;
  392.     CGraphicsState     rememberGState;
  393.     
  394.     itsView->ViewToQDRect(area, qdArea);
  395.  
  396.     CDrawPerDevice device(qdArea);
  397.     while (device.NextDevice(pixelSize)) 
  398.     {
  399. //        Only draw us if we are on a non B & W monitor
  400.         if (pixelSize >= 4) 
  401.         {    
  402.             SetIfBkColor(gRGBWhite);
  403.             EraseRect(qdArea);
  404.         }
  405.     }    
  406. } // TWhiteBackgroundAdorner::Draw
  407.  
  408.  
  409. //--------------------------------------------------------------------------------------------------
  410. #pragma segment A3DOpen
  411.  
  412. pascal void TGrayBackgroundAdorner::Initialize()
  413. {
  414.     inherited::Initialize();
  415. }
  416.  
  417.  
  418. //--------------------------------------------------------------------------------------------------
  419. #pragma segment A3DOpen
  420.  
  421. pascal void TGrayBackgroundAdorner::IGrayBackgroundAdorner(Boolean freeOnDeletion)
  422. {
  423.  
  424.     this->IAdorner(kGrayBackgroundAdorner,freeOnDeletion);
  425.  
  426. } // T3DGrayBackgroundAdorner::I3DGrayBackgroundAdorner
  427.  
  428.  
  429. //--------------------------------------------------------------------------------------------------
  430. #pragma segment A3DRes
  431.  
  432. pascal void TGrayBackgroundAdorner::Draw(TView* itsView, const VRect& area)
  433. {
  434.  
  435.     CRect            qdArea;
  436.     short            pixelSize;
  437.     CGraphicsState     rememberGState;
  438.     
  439.     itsView->ViewToQDRect(area, qdArea);
  440.  
  441.     CDrawPerDevice device(qdArea);
  442.     while (device.NextDevice(pixelSize)) 
  443.     {
  444.         if (pixelSize >= 4) 
  445.         {    
  446. //            Erase because we want our subviews to draw on gray
  447.             SetIfBkColor(kLightGray);
  448.             EraseRect(qdArea);
  449.         }
  450.     }    
  451. } // TGrayBackgroundAdorner::Draw
  452.  
  453.  
  454. //--------------------------------------------------------------------------------------------------
  455. #pragma segment A3DOpen
  456.  
  457. pascal void T3DGrayBackgroundAdorner::Initialize()
  458. {
  459.     inherited::Initialize();
  460. }
  461.  
  462.  
  463. //--------------------------------------------------------------------------------------------------
  464. #pragma segment A3DOpen
  465.  
  466. pascal void T3DGrayBackgroundAdorner::I3DGrayBackgroundAdorner(Boolean freeOnDeletion)
  467. {
  468.  
  469.     this->IGrayBackgroundAdorner(freeOnDeletion);
  470.  
  471. } // T3DGrayBackgroundAdorner::I3DGrayBackgroundAdorner
  472.  
  473.  
  474. //--------------------------------------------------------------------------------------------------
  475. #pragma segment A3DRes
  476.  
  477. pascal void T3DGrayBackgroundAdorner::Draw(TView* itsView, const VRect& area)
  478. {
  479.  
  480.     CRect            qdArea, frame;
  481.     VRect            viewRect;
  482.     short            pixelSize;
  483.     CGraphicsState     rememberGState;
  484.     
  485. //    Erase the background in gray
  486.     inherited:: Draw(itsView,area);
  487.  
  488.     itsView->ViewToQDRect(area, qdArea);
  489.     itsView->GetAdornExtent(viewRect);
  490.     itsView->ViewToQDRect(viewRect, frame);
  491.  
  492.     CDrawPerDevice device(qdArea);    
  493.     while (device.NextDevice(pixelSize)) 
  494.     {
  495. //        Only draw on non- B & W
  496.         if (pixelSize >= 4) 
  497.         {
  498.             SetIfColor(gRGBWhite);
  499.             MoveTo(frame.right-1, frame.top);
  500.             LineTo(frame.left, frame.top);
  501.             LineTo(frame.left, frame.bottom);
  502.         
  503.             SetIfColor(kMediumLightGray);    
  504.             MoveTo(frame.left+1, frame.bottom-1);
  505.             LineTo(frame.right-1, frame.bottom-1);
  506.             LineTo(frame.right-1, frame.top+1);
  507.         }
  508.     }
  509.     
  510. } // T3DGrayBackgroundAdorner::Draw
  511.  
  512.  
  513. //--------------------------------------------------------------------------------------------------
  514. #pragma segment A3DOpen
  515.  
  516. pascal void T3DLineTopAdorner::Initialize()
  517. {
  518.     inherited::Initialize();
  519. }
  520.  
  521.  
  522. //--------------------------------------------------------------------------------------------------
  523. #pragma segment A3DOpen
  524.  
  525. pascal void T3DLineTopAdorner::I3DLineTopAdorner(Boolean freeOnDeletion)
  526. {
  527.  
  528.     this->IAdorner(k3DLineTopAdorner,freeOnDeletion);
  529.  
  530. } // T3DLineTopAdorner::I3DLineTopAdorner
  531.  
  532.  
  533. //--------------------------------------------------------------------------------------------------
  534. #pragma segment A3DRes
  535.  
  536. pascal void T3DLineTopAdorner::Draw(TView* itsView, const VRect& area)
  537. {
  538.  
  539.     CRect            qdArea, frame;
  540.     VRect            viewRect;
  541.     short            pixelSize;
  542.     CGraphicsState  rememberGState;
  543.     
  544.     itsView->ViewToQDRect(area, qdArea);
  545.     itsView->GetAdornExtent(viewRect);
  546.     itsView->ViewToQDRect(viewRect, frame);
  547.     
  548.     CDrawPerDevice device(qdArea);
  549.     while (device.NextDevice(pixelSize)) 
  550.     {
  551. //        Draw a gray and white line for non- B & W
  552.         if (pixelSize >= 4) 
  553.         {
  554.             SetIfColor(kMediumLightGray);    
  555.             MoveTo(frame.left, frame.top);
  556.             LineTo(frame.right, frame.top);
  557.     
  558.             SetIfColor(gRGBWhite);
  559.             MoveTo(frame.left, frame.top + 1);
  560.             LineTo(frame.right, frame.top + 1);
  561.         }
  562. //        Draw a regular black line
  563.         else
  564.         {
  565.     
  566.             PenPat(&qd.black);
  567.             MoveTo(frame.left, frame.top);
  568.             LineTo(frame.right, frame.top);
  569.         }
  570.     }
  571.  
  572. } // T3DLineTopAdorner::Draw
  573.  
  574.  
  575. //--------------------------------------------------------------------------------------------------
  576. #pragma segment A3DOpen
  577.  
  578. pascal void T3DLineBottomAdorner::Initialize()
  579. {
  580.     inherited::Initialize();
  581. }
  582.  
  583.  
  584. //--------------------------------------------------------------------------------------------------
  585. #pragma segment A3DOpen
  586.  
  587. pascal void T3DLineBottomAdorner::I3DLineBottomAdorner(Boolean freeOnDeletion)
  588. {
  589.  
  590.     this->IAdorner(k3DLineBottomAdorner,freeOnDeletion);
  591.  
  592. } // T3DLineBottomAdorner::I3DLineBottomAdorner
  593.  
  594.  
  595. //--------------------------------------------------------------------------------------------------
  596. #pragma segment A3DRes
  597.  
  598. pascal void T3DLineBottomAdorner::Draw(TView* itsView, const VRect& area)
  599. {
  600.  
  601.     CRect            qdArea, frame;
  602.     VRect            viewRect;
  603.     short            pixelSize;
  604.     CGraphicsState  rememberGState;
  605.     
  606.     itsView->ViewToQDRect(area, qdArea);
  607.     itsView->GetAdornExtent(viewRect);
  608.     itsView->ViewToQDRect(viewRect, frame);
  609.     
  610.     CDrawPerDevice device(qdArea);    
  611.     while (device.NextDevice(pixelSize)) 
  612.     {
  613. //        Draw a gray and white line for non- B & W
  614.         if (pixelSize >= 4) 
  615.         {
  616.             SetIfColor(kMediumLightGray);    
  617.             MoveTo(frame.left, frame.bottom - 1);
  618.             LineTo(frame.right, frame.bottom - 1);
  619.     
  620.             SetIfColor(gRGBWhite);
  621.             MoveTo(frame.left, frame.bottom);
  622.             LineTo(frame.right, frame.bottom);
  623.         }
  624. //        Draw a regular black line
  625.         else
  626.         {
  627.     
  628.             PenPat(&qd.black);
  629.             MoveTo(frame.left, frame.bottom - 1);
  630.             LineTo(frame.right, frame.bottom - 1);
  631.         }
  632.     }
  633.  
  634. } // T3DLineBottomAdorner::Draw
  635.  
  636. //--------------------------------------------------------------------------------------------------
  637. #pragma segment A3DOpen
  638.  
  639. pascal void T3DLineLeftAdorner::Initialize()
  640. {
  641.     inherited::Initialize();
  642. }
  643.  
  644.  
  645. //--------------------------------------------------------------------------------------------------
  646. #pragma segment A3DOpen
  647.  
  648. pascal void T3DLineLeftAdorner::I3DLineLeftAdorner(Boolean freeOnDeletion)
  649. {
  650.  
  651.     this->IAdorner(k3DLineLeftAdorner,freeOnDeletion);
  652.  
  653. } // T3DLineLeftAdorner::I3DLineLeftAdorner
  654.  
  655.  
  656. //--------------------------------------------------------------------------------------------------
  657. #pragma segment A3DRes
  658.  
  659. pascal void T3DLineLeftAdorner::Draw(TView* itsView, const VRect& area)
  660. {
  661.  
  662.     CRect            qdArea, frame;
  663.     VRect            viewRect;
  664.     short            pixelSize;
  665.     CGraphicsState  rememberGState;
  666.     
  667.     itsView->ViewToQDRect(area, qdArea);
  668.     itsView->GetAdornExtent(viewRect);
  669.     itsView->ViewToQDRect(viewRect, frame);
  670.     
  671.     CDrawPerDevice device(qdArea);
  672.     while (device.NextDevice(pixelSize)) 
  673.     {
  674. //        Draw a gray and white line for non- B & W
  675.         if (pixelSize >= 4) 
  676.         {
  677.             SetIfColor(kMediumLightGray);    
  678.             MoveTo(frame.left, frame.top);
  679.             LineTo(frame.left, frame.bottom);
  680.     
  681.             SetIfColor(gRGBWhite);
  682.             MoveTo(frame.left + 1, frame.top);
  683.             LineTo(frame.left + 1, frame.bottom);
  684.         }
  685. //        Draw a regular black line
  686.         else
  687.         {
  688.     
  689.             PenPat(&qd.black);
  690.             MoveTo(frame.left, frame.top);
  691.             LineTo(frame.left, frame.bottom);
  692.         }
  693.     }
  694.  
  695. } // T3DLineLeftAdorner::Draw
  696.  
  697. //--------------------------------------------------------------------------------------------------
  698. #pragma segment A3DOpen
  699.  
  700. pascal void T3DLineRightAdorner::Initialize()
  701. {
  702.     inherited::Initialize();
  703. }
  704.  
  705.  
  706. //--------------------------------------------------------------------------------------------------
  707. #pragma segment A3DOpen
  708.  
  709. pascal void T3DLineRightAdorner::I3DLineRightAdorner(Boolean freeOnDeletion)
  710. {
  711.  
  712.     this->IAdorner(k3DLineRightAdorner,freeOnDeletion);
  713.  
  714. } // T3DLineRightAdorner::I3DLineRightAdorner
  715.  
  716.  
  717. //--------------------------------------------------------------------------------------------------
  718. #pragma segment A3DRes
  719.  
  720. pascal void T3DLineRightAdorner::Draw(TView* itsView, const VRect& area)
  721. {
  722.  
  723.     CRect            qdArea, frame;
  724.     VRect            viewRect;
  725.     short            pixelSize;
  726.     CGraphicsState  rememberGState;
  727.     
  728.     itsView->ViewToQDRect(area, qdArea);
  729.     itsView->GetAdornExtent(viewRect);
  730.     itsView->ViewToQDRect(viewRect, frame);
  731.     
  732.     CDrawPerDevice device(qdArea);    
  733.     while (device.NextDevice(pixelSize)) 
  734.     {
  735. //        Draw a gray and white line for non- B & W
  736.         if (pixelSize >= 4) 
  737.         {
  738.             SetIfColor(kMediumLightGray);    
  739.             MoveTo(frame.right - 1, frame.top);
  740.             LineTo(frame.right -1, frame.bottom);
  741.     
  742.             SetIfColor(gRGBWhite);
  743.             MoveTo(frame.right, frame.top);
  744.             LineTo(frame.right, frame.bottom);
  745.         }
  746. //        Draw a regular black line
  747.         else
  748.         {
  749.     
  750.             PenPat(&qd.black);
  751.             MoveTo(frame.right - 1, frame.top);
  752.             LineTo(frame.right - 1, frame.bottom);
  753.         }
  754.     }
  755.  
  756. } // T3DLineRightAdorner::Draw
  757.  
  758.  
  759. //--------------------------------------------------------------------------------------------------
  760. #pragma segment A3DOpen
  761.  
  762. pascal void T3DFrameAdorner::Initialize()
  763. {
  764.     inherited::Initialize();
  765. }
  766.  
  767.  
  768. //--------------------------------------------------------------------------------------------------
  769. #pragma segment A3DOpen
  770.  
  771. pascal void T3DFrameAdorner::I3DFrameAdorner(Boolean freeOnDeletion)
  772. {
  773.  
  774.     this->IAdorner(k3DFrameAdorner,freeOnDeletion);
  775.  
  776. } // T3DFrameAdorner::I3DFrameAdorner
  777.  
  778.  
  779. //--------------------------------------------------------------------------------------------------
  780. #pragma segment A3DRes
  781.  
  782. pascal void T3DFrameAdorner::Draw(TView* itsView, const VRect& area)
  783. {
  784.  
  785.     CRect            qdArea, frame;
  786.     VRect            viewRect;
  787.     short            pixelSize;
  788.     CGraphicsState  rememberGState;
  789.  
  790.     itsView->ViewToQDRect(area, qdArea);
  791.     itsView->GetAdornExtent(viewRect);
  792.     itsView->ViewToQDRect(viewRect, frame);
  793.     
  794.     CDrawPerDevice device(qdArea);
  795.     while (device.NextDevice(pixelSize))
  796.     {
  797. //        Draw a gray and white frame with black outline
  798.         if (pixelSize >= 4) {
  799.  
  800.             SetIfColor(kMediumLightGray);
  801.             MoveTo(frame.right, frame.top);
  802.             LineTo(frame.left, frame.top);
  803.             LineTo(frame.left, frame.bottom);
  804.         
  805.             SetIfColor(gRGBWhite);    
  806.             MoveTo(frame.left +1, frame.bottom -1);
  807.             LineTo(frame.right -1, frame.bottom -1);
  808.             LineTo(frame.right -1, frame.top + 1);
  809.             
  810.             SetIfColor(gRGBBlack);    
  811.             InsetRect(frame, 1, 1);
  812.             FrameRect(frame);
  813.             InsetRect(frame, -1, -1);
  814.         }
  815. //        Draw a regular frame
  816.         else
  817.         {
  818.             PenPat(&qd.black);
  819.             InsetRect(frame, 1, 1);
  820.             FrameRect(frame);
  821.             InsetRect(frame, -1, -1);
  822.         }
  823.     }
  824.  
  825. } // T3DFrameAdorner::Draw
  826.  
  827.  
  828.  
  829. //==================================================================================== 
  830. //    ••••••••••••••••• TControl classes and auxiliary adorners •••••••••••••••••••••••
  831. //==================================================================================== 
  832.  
  833. //-------------------------------------------------------------------------------------
  834. // T3DCheckBox::Initialize
  835. //-------------------------------------------------------------------------------------
  836. #pragma segment A3DControlOpen
  837.  
  838. pascal void T3DCheckBox::Initialize ()                // OVERRIDE 
  839. {
  840.  
  841.     inherited::Initialize();
  842.     
  843.     fBackColor = kLightGray;
  844.     fForeColor = gRGBBlack;
  845.     fDrawBox = VRect(1, 0, 15, 14);        //    A standard check box is 14x14
  846.     
  847. } // T3DCheckBox::Initialize
  848.  
  849.  
  850.  
  851. //-------------------------------------------------------------------------------------
  852. // T3DCheckBox::DoPostCreate
  853. //-------------------------------------------------------------------------------------
  854. #pragma segment A3DControlOpen
  855.  
  856. pascal void T3DCheckBox::DoPostCreate (TDocument *itsDocument) // OVERRIDE 
  857. {
  858.     VRect                    theRect;
  859.     TDrawingEnvironment     *environment;
  860.     
  861.     inherited::DoPostCreate (itsDocument);
  862.     
  863. //    If we have a drawing environment, use it for drawing!
  864.     if (environment = this->GetDrawingEnvironment())
  865.     {
  866.         this->SetBackColor(environment->fBackgroundColor);
  867.         this->InstallColor(environment->fForegroundColor, FALSE);
  868.     }
  869.     this->ControlArea(theRect);
  870.  
  871. //    Center the check box vertically
  872.     long height = theRect.bottom - theRect.top;
  873.     height -= 14;
  874.     long top = height / 2;
  875.     fDrawBox.top += top;
  876.     fDrawBox.bottom += top;
  877.     
  878. } // T3DCheckBox::DoPostCreate
  879.  
  880.  
  881. //-------------------------------------------------------------------------------------
  882. // T3DCheckBox::I3DCheckBox
  883. //-------------------------------------------------------------------------------------
  884. #pragma segment A3DControlOpen
  885.  
  886. pascal void T3DCheckBox::I3DCheckBox (TView* itsSuperView, const VPoint& itsLocation,
  887.                                  const VPoint& itsSize, SizeDeterminer itsHSizeDet,
  888.                                  SizeDeterminer itsVSizeDet, const CStr255& itsLabel,
  889.                                  Boolean isTurnedOn)
  890. {
  891.     VRect                    theRect;
  892.     TDrawingEnvironment     *environment;
  893.     
  894.     this->ICheckBox (itsSuperView, itsLocation, itsSize, itsHSizeDet, itsVSizeDet, itsLabel, isTurnedOn);
  895.     
  896. //    If we have a drawing environment, use it for drawing!
  897.     if (environment = this->GetDrawingEnvironment())
  898.     {
  899.         this->SetBackColor(environment->fBackgroundColor);
  900.         this->InstallColor(environment->fForegroundColor, FALSE);
  901.     }
  902.     this->ControlArea(theRect);
  903.  
  904. //    Center the check box vertically
  905.     long height = theRect.bottom - theRect.top;
  906.     height -= 14;
  907.     long top = height / 2;
  908.     fDrawBox.top += top;
  909.     fDrawBox.bottom += top;
  910.     
  911.  
  912. } // T3DCheckBox::I3DCheckBox
  913.  
  914.  
  915. //-------------------------------------------------------------------------------------
  916. // T3DCheckBox::Clone
  917. //-------------------------------------------------------------------------------------
  918. #pragma segment A3DControlNonRes
  919.  
  920. pascal TObject* T3DCheckBox::Clone ()                // OVERRIDE 
  921. {
  922.  
  923.     T3DCheckBox*    aClonedCheckBox;
  924.  
  925.     aClonedCheckBox = (T3DCheckBox *)(inherited::Clone ());
  926.  
  927.     aClonedCheckBox->fBackColor = fBackColor;
  928.     aClonedCheckBox->fForeColor = fForeColor;
  929.     
  930.     return aClonedCheckBox;
  931.     
  932. } // T3DCheckBox::Clone
  933.  
  934.  
  935. //-------------------------------------------------------------------------------------
  936. // T3DCheckBox::Free
  937. //-------------------------------------------------------------------------------------
  938. #pragma segment A3DControlClose
  939.  
  940. pascal void T3DCheckBox::Free ()                    // OVERRIDE 
  941. {
  942.     inherited::Free ();
  943.     
  944. } // T3DCheckBox::Free
  945.  
  946.  
  947. //----------------------------------------------------------------------------------------
  948. // T3DCheckBox::Draw:
  949. //----------------------------------------------------------------------------------------
  950. #pragma segment A3DControlRes
  951.  
  952. pascal void T3DCheckBox::Draw (const VRect& /*area*/)    
  953. {
  954.     VRect             theRect;
  955.     CRect            qdArea;
  956.     CStr255            label;
  957.     CGraphicsState    remember;
  958.     
  959.     this->ControlArea(theRect);
  960.     this->ViewToQDRect(theRect, qdArea);
  961.  
  962.     this->DrawBox();
  963.     this->DrawCheck();
  964.     
  965.     this->GetText (label);    
  966.     CRect textBox = qdArea;
  967.  
  968. //    Move the text 3 pixels to the right of the check box
  969.     textBox.left += (short) fDrawBox.right + 3;
  970.     DrawBoxText (label, textBox, FALSE);
  971.     
  972. } // T3DCheckBox::Draw
  973.  
  974.  
  975. //-------------------------------------------------------------------------------------
  976. // T3DButton::DoMouseCommand
  977. //-------------------------------------------------------------------------------------
  978. #pragma segment A3DControlSelCommand
  979.  
  980. pascal void T3DCheckBox::DoMouseCommand(VPoint& theMouse,
  981.                                                  TToolboxEvent* ,
  982.                                                  CPoint)        // override 
  983. {
  984.     TControlTracker * aControlTracker = new TControlTracker;
  985.     aControlTracker->IControlTracker(this, theMouse);
  986.     this->PostCommand(aControlTracker);
  987. } // T3DCheckBox::DoMouseCommand
  988.  
  989. //-------------------------------------------------------------------------------------
  990. // T3DCheckBox::TrackMouse
  991. //-------------------------------------------------------------------------------------
  992. #pragma segment A3DControlSelCommand
  993.  
  994. pascal void T3DCheckBox::TrackMouse(TrackPhase aTrackPhase,
  995.                                                              VPoint& ,
  996.                                                              // anchorPoint
  997.                                                              VPoint& ,
  998.                                                              // previousPoint
  999.                                                              VPoint& nextPoint,
  1000.                                                              Boolean)                            // OVERRIDE
  1001. {
  1002.     Boolean state = false;
  1003.     
  1004.     if (!this->IsDimmed())
  1005.         switch(aTrackPhase)
  1006.         {
  1007.             case trackBegin:
  1008.                 state = fHilite;
  1009.                 this->HiliteState(TRUE, kRedraw);
  1010.                 break;
  1011.             case trackContinue:
  1012.                 if (this->ContainsMouse(nextPoint))
  1013.                     this->HiliteState(TRUE, kRedraw);
  1014.                 else
  1015.                     this->HiliteState(state, kRedraw);
  1016.                 break;
  1017.             case trackEnd:
  1018.                 if (this->ContainsMouse(nextPoint))
  1019.                 {
  1020.                     this->HiliteState(FALSE, this->IsOn());
  1021.                     this->HandleEvent(fEventNumber, this, NULL);
  1022.                 }
  1023.                 break;
  1024.         }
  1025. }    // T3DCheckBox::TrackMouse
  1026.  
  1027.  
  1028. //----------------------------------------------------------------------------------------
  1029. // T3DCheckBox::SetLongVal:
  1030. //    Override the way the control works so that we don't call the CDEF
  1031. //----------------------------------------------------------------------------------------
  1032. #pragma segment A3DControlRes
  1033.  
  1034. pascal void T3DCheckBox::SetLongVal(VCoordinate itsVal,
  1035.                                 Boolean /*redraw*/)
  1036. {
  1037.  
  1038.     itsVal = Max(fLongMin, Min(itsVal, fLongMax));
  1039.     if (itsVal != fLongVal)
  1040.     {
  1041.         fLongVal = itsVal;
  1042.         CRect tempRect;
  1043.         this->ViewToQDRect(fDrawBox, tempRect);
  1044.         InsetRect(tempRect, 2,2);
  1045.         this->InvalidateRect(tempRect);
  1046.     }
  1047. } // T3DCheckBox::SetLongVal
  1048.  
  1049.  
  1050. //----------------------------------------------------------------------------------------
  1051. // T3DCheckBox::HiliteState:
  1052. //----------------------------------------------------------------------------------------
  1053. #pragma segment A3DControlNonRes
  1054.  
  1055. pascal void T3DCheckBox::HiliteState(Boolean state,Boolean redraw)
  1056. {
  1057.     if (state != fHilite)
  1058.     {
  1059.         fHilite = state;
  1060.         if (state)                                // hilite adorner draws the hilite state
  1061.             this->AddAdorner(gHiliteAdorner, kAdornLast - 5, kDontRedraw);
  1062.         else
  1063.             this->DeleteAdorner(gHiliteAdorner, kDontRedraw);
  1064.         if (redraw)
  1065.             this->Hilite();
  1066.     }
  1067. } // T3DCheckBox::HiliteState
  1068.  
  1069.  
  1070. //----------------------------------------------------------------------------------------
  1071. // T3DCheckBox::DimState:
  1072. //----------------------------------------------------------------------------------------
  1073. #pragma segment A3DControlNonRes
  1074.  
  1075. pascal void T3DCheckBox::DimState(Boolean state,
  1076.                                Boolean redraw)
  1077. {
  1078.     if (state != fDimmed)
  1079.     {
  1080.         fDimmed = state;
  1081.         if (state)                                // dim adorner draws the dim state
  1082.             this->AddAdorner(gDimAdorner, kAdornLast - 10, kDontRedraw);
  1083.         else
  1084.             this->DeleteAdorner(gDimAdorner, kDontRedraw);
  1085.         if (redraw)
  1086.             this->DrawContents();                // Draw change immediately
  1087.     }
  1088. } // T3DCheckBox::DimState
  1089.  
  1090.  
  1091. //-------------------------------------------------------------------------------------
  1092. // T3DCheckBox::Hilite
  1093. //-------------------------------------------------------------------------------------
  1094. #pragma segment A3DControlRes
  1095.  
  1096. pascal void T3DCheckBox::Hilite ()        // OVERRIDE
  1097. {
  1098.  
  1099.     VRect                area;
  1100.     CRect                qdArea, qdBox;
  1101.     CGraphicsState        rememberGState;
  1102.     
  1103.     #if qDebug
  1104.         this->AssumeFocused ();
  1105.     #endif
  1106.     
  1107.     this->ControlArea (area);
  1108.     this->ViewToQDRect (area, qdArea);
  1109.     this->ViewToQDRect(fDrawBox, qdBox);
  1110.  
  1111.     CPenNormal();
  1112.     if (fHilite) 
  1113.     {
  1114.         InsetRect(qdBox, 2, 2);
  1115.         FrameRect(qdBox);
  1116.     }
  1117.     else
  1118.         this->DrawCheck();
  1119. } // T3DCheckBox::Hilite
  1120.  
  1121.  
  1122. //-------------------------------------------------------------------------------------
  1123. // T3DCheckBox::Dim
  1124. //-------------------------------------------------------------------------------------
  1125. #pragma segment A3DControlRes
  1126.  
  1127. pascal void T3DCheckBox::Dim ()        // OVERRIDE
  1128. {
  1129.     VRect             area;
  1130.     CRect             qdArea;
  1131.     CGraphicsState    rememberGState;
  1132.     
  1133.     this->ControlArea (area);
  1134.     area.left += fDrawBox.right;
  1135.     this->ViewToQDRect (area, qdArea);
  1136.  
  1137.     short pixelSize;
  1138.     CDrawPerDevice device(qdArea);
  1139.     while (device.NextDevice (pixelSize)) 
  1140.     {
  1141. //        If in B & W, do the standard gray pattern.  Non B & W is taken care of in
  1142. //            the DrawCheck and DrawBox routines
  1143.         if (pixelSize < 2)
  1144.         {
  1145.             #if qDebug
  1146.                 this->AssumeFocused ();
  1147.             #endif
  1148.             
  1149.             InsetRect (qdArea, 1, 1);
  1150.             
  1151.             PenPat (&qd.gray);
  1152.             PenMode (patBic);
  1153.             PaintRect (qdArea);
  1154.  
  1155.             InsetRect (qdArea, -1, -1);
  1156.         }
  1157.     }
  1158. } // T3DCheckBox::Dim
  1159.  
  1160. //-------------------------------------------------------------------------------------
  1161. // T3DCheckBox::DrawBoxText
  1162. //-------------------------------------------------------------------------------------
  1163. #pragma segment A3DControlRes
  1164.  
  1165. pascal void T3DCheckBox::DrawBoxText (const CStr255& s, const CRect& box, Boolean preferOutline)
  1166. {
  1167.     FontInfo         theFontInfo;
  1168.     CRect             localBox = box;
  1169.     CRect             qdArea;
  1170.     CGraphicsState    rememberGState;
  1171.     
  1172.     CWhileOutlinePreferred setOP (preferOutline);
  1173.     
  1174.     short textHeight = MAGetFontInfo (theFontInfo);
  1175.     CPoint boxSize = localBox.GetSize ();
  1176.     
  1177. //    Center the text vertically
  1178.     localBox.top += (boxSize.v - textHeight) / 2;
  1179.     MoveTo (localBox.left, localBox.top + theFontInfo.ascent);
  1180.     
  1181.     short pixelSize;
  1182.     CDrawPerDevice device(localBox);
  1183.     while (device.NextDevice (pixelSize)) 
  1184.     {
  1185.     //    If we're dimmed, draw in gray, else draw in the fore color
  1186.         if (pixelSize > 2)
  1187.         {    
  1188.             SetIfBkColor(fBackColor);
  1189.             if (this->IsDimmed())
  1190.                 SetIfColor(kMediumGray);
  1191.             else
  1192.                 SetIfColor(fForeColor);
  1193.         }
  1194.         MoveTo (localBox.left, localBox.top + theFontInfo.ascent);
  1195.         DrawString(s);
  1196.     }
  1197.  
  1198. } // T3DCheckBox::DrawBoxText
  1199.  
  1200.  
  1201. //-------------------------------------------------------------------------------------
  1202. // T3DCheckBox::DrawBox
  1203. //-------------------------------------------------------------------------------------
  1204. #pragma segment A3DControlRes
  1205.  
  1206. pascal void T3DCheckBox::DrawBox()
  1207. {
  1208.     CRect            qdBox;
  1209.     short            pixelSize;
  1210.     CGraphicsState    rememberGState;
  1211.     
  1212.     this->ViewToQDRect(fDrawBox, qdBox);
  1213.     
  1214.     CDrawPerDevice device(qdBox);
  1215.     while (device.NextDevice (pixelSize)) 
  1216.     {
  1217. //            Draw the 3D effect if we're in non B & W
  1218.         if (pixelSize > 2) 
  1219.         {
  1220.             if (!this->IsDimmed())
  1221.             {
  1222.                 SetIfColor(gRGBWhite);    
  1223.                 MoveTo(qdBox.left+1, qdBox.bottom-1);
  1224.                 LineTo(qdBox.right-1, qdBox.bottom-1);
  1225.                 LineTo(qdBox.right-1, qdBox.top+1);
  1226.     
  1227.                 SetIfColor(kMediumLightGray);
  1228.                 MoveTo(qdBox.right, qdBox.top);
  1229.                 LineTo(qdBox.left, qdBox.top);
  1230.                 LineTo(qdBox.left, qdBox.bottom);
  1231.                 SetIfColor(fForeColor);
  1232.             }
  1233.             else
  1234.                 SetIfColor(kMediumGray);
  1235.         }
  1236.         else
  1237.             SetIfColor(gRGBBlack);
  1238.  
  1239.     //    Now draw the regular check box
  1240.         InsetRect(qdBox, 1, 1);
  1241.         FrameRect(qdBox);            
  1242.         InsetRect(qdBox, -1, -1);
  1243.     }
  1244.  
  1245. }
  1246.  
  1247.  
  1248. //-------------------------------------------------------------------------------------
  1249. // T3DCheckBox::DrawCheck
  1250. //-------------------------------------------------------------------------------------
  1251. #pragma segment A3DControlRes
  1252.  
  1253. pascal void T3DCheckBox::DrawCheck()
  1254. {
  1255.     CRect            qdBox;
  1256.     CGraphicsState    rememberGState;
  1257.     
  1258.     this->ViewToQDRect(fDrawBox, qdBox);
  1259.  
  1260.     InsetRect(qdBox, 2, 2);
  1261.     SetIfBkColor(gRGBWhite);
  1262.     EraseRect(qdBox);
  1263.  
  1264. //    Draw the check if we're on
  1265.     if (this->IsOn())
  1266.     {
  1267.         short pixelSize;
  1268.         CDrawPerDevice device(qdBox);
  1269.         while (device.NextDevice (pixelSize)) 
  1270.         {
  1271.             if (pixelSize > 2) 
  1272.                 if (this->IsDimmed())
  1273.                     SetIfColor(kMediumGray);
  1274.  
  1275.             MoveTo(qdBox.left-1, qdBox.bottom);
  1276.             LineTo(qdBox.right-1, qdBox.top);
  1277.             MoveTo(qdBox.left, qdBox.top);
  1278.             LineTo(qdBox.right, qdBox.bottom);
  1279.         }
  1280.     }
  1281. }
  1282.  
  1283.  
  1284. //-------------------------------------------------------------------------------------
  1285. // T3DCheckBox::DrawCheck
  1286. //        Override because we don't want the inherited method, which uses the CDEF
  1287. //-------------------------------------------------------------------------------------
  1288. #pragma segment A3DControlRes
  1289.  
  1290. pascal void T3DCheckBox::InstallColor(const CRGBColor& theColor,
  1291.                                    Boolean redraw)
  1292. {
  1293.     fForeColor = theColor;
  1294.     if (redraw)
  1295.         this->ForceRedraw();
  1296. }
  1297.  
  1298.  
  1299. //-------------------------------------------------------------------------------------
  1300. // T3DRadio::Initialize
  1301. //-------------------------------------------------------------------------------------
  1302. #pragma segment A3DControlOpen
  1303.  
  1304. pascal void T3DRadio::Initialize ()                // OVERRIDE 
  1305. {
  1306.  
  1307.     inherited::Initialize();
  1308.     
  1309.     fBackColor = kLightGray;
  1310.     fForeColor = gRGBBlack;
  1311.     fDrawBox = VRect(2, 0, 14, 12);        //    A radio button is 12x12
  1312.     
  1313. } // T3DRadio::Initialize
  1314.  
  1315.  
  1316.  
  1317. //-------------------------------------------------------------------------------------
  1318. // T3DRadio::DoPostCreate
  1319. //-------------------------------------------------------------------------------------
  1320. #pragma segment A3DControlOpen
  1321.  
  1322. pascal void T3DRadio::DoPostCreate (TDocument *itsDocument) // OVERRIDE 
  1323. {
  1324.     VRect                    theRect;
  1325.     TDrawingEnvironment     *environment;
  1326.     
  1327.     inherited::DoPostCreate (itsDocument);
  1328.     
  1329. //    If we have a drawing environment, use it!
  1330.     if (environment = this->GetDrawingEnvironment())
  1331.     {
  1332.         this->SetBackColor(environment->fBackgroundColor);
  1333.         this->InstallColor(environment->fForegroundColor, FALSE);
  1334.     }
  1335.     
  1336. //    Center the button vertically
  1337.     this->ControlArea(theRect);
  1338.     long height = theRect.bottom - theRect.top;
  1339.     height -= 12;
  1340.     long top = height / 2;
  1341.     fDrawBox.top += top;
  1342.     fDrawBox.bottom += top;
  1343.     
  1344. } // T3DRadio::DoPostCreate
  1345.  
  1346.  
  1347. //-------------------------------------------------------------------------------------
  1348. // T3DRadio::I3DRadio
  1349. //-------------------------------------------------------------------------------------
  1350. #pragma segment A3DControlOpen
  1351.  
  1352. pascal void T3DRadio::I3DRadio (TView* itsSuperView, const VPoint& itsLocation,
  1353.                                  const VPoint& itsSize, SizeDeterminer itsHSizeDet,
  1354.                                  SizeDeterminer itsVSizeDet, const CStr255& itsLabel,
  1355.                                  Boolean isTurnedOn)
  1356. {
  1357.     VRect                    theRect;
  1358.     TDrawingEnvironment     *environment;
  1359.     
  1360.     this->IRadio (itsSuperView, itsLocation, itsSize, itsHSizeDet, itsVSizeDet, itsLabel, isTurnedOn);
  1361.     
  1362. //    If we have a drawing environment, use it!
  1363.     if (environment = this->GetDrawingEnvironment())
  1364.     {
  1365.         this->SetBackColor(environment->fBackgroundColor);
  1366.         this->InstallColor(environment->fForegroundColor, FALSE);
  1367.     }
  1368.     
  1369. //    Center the button vertically
  1370.     this->ControlArea(theRect);
  1371.     long height = theRect.bottom - theRect.top;
  1372.     height -= 12;
  1373.     long top = height / 2;
  1374.     fDrawBox.top += top;
  1375.     fDrawBox.bottom += top;
  1376.     
  1377.  
  1378. } // T3DRadio::I3DRadio
  1379.  
  1380.  
  1381. //-------------------------------------------------------------------------------------
  1382. // T3DRadio::Clone
  1383. //-------------------------------------------------------------------------------------
  1384. #pragma segment A3DControlNonRes
  1385.  
  1386. pascal TObject* T3DRadio::Clone ()                // OVERRIDE 
  1387. {
  1388.  
  1389.     T3DRadio*    aClonedRadio;
  1390.  
  1391.     aClonedRadio = (T3DRadio *)(inherited::Clone ());
  1392.  
  1393.     aClonedRadio->fBackColor = fBackColor;
  1394.     aClonedRadio->fForeColor = fForeColor;
  1395.     
  1396.     return aClonedRadio;
  1397.     
  1398. } // T3DRadio::Clone
  1399.  
  1400.  
  1401. //-------------------------------------------------------------------------------------
  1402. // T3DRadio::Free
  1403. //-------------------------------------------------------------------------------------
  1404. #pragma segment A3DControlClose
  1405.  
  1406. pascal void T3DRadio::Free ()                    // OVERRIDE 
  1407. {
  1408.     inherited::Free ();
  1409.     
  1410. } // T3DRadio::Free
  1411.  
  1412.  
  1413. //-------------------------------------------------------------------------------------
  1414. // T3DRadio::Draw
  1415. //-------------------------------------------------------------------------------------
  1416. #pragma segment A3DControlRes
  1417.  
  1418. pascal void T3DRadio::Draw (const VRect& /*area*/)    
  1419. {
  1420.     VRect             theRect;
  1421.     CRect            qdArea;
  1422.     CStr255            label;
  1423.     CGraphicsState    rememberGState;
  1424.     
  1425.     this->ControlArea(theRect);
  1426.     this->ViewToQDRect(theRect, qdArea);
  1427.  
  1428.     this->DrawBox();
  1429.     this->DrawCheck();
  1430.     
  1431. //    Draw the button text 4 pixels to the right of the button
  1432.     this->GetText (label);    
  1433.     CRect textBox = qdArea;
  1434.     textBox.left += (short) fDrawBox.right + 4;
  1435.     DrawBoxText (label, textBox, FALSE);
  1436.     
  1437. } // T3DRadio::Draw
  1438.  
  1439.  
  1440. //-------------------------------------------------------------------------------------
  1441. // T3DButton::DoMouseCommand
  1442. //-------------------------------------------------------------------------------------
  1443. #pragma segment A3DControlSelCommand
  1444.  
  1445. pascal void T3DRadio::DoMouseCommand(VPoint& theMouse,
  1446.                                                  TToolboxEvent* ,
  1447.                                                  CPoint)        // override 
  1448. {
  1449.     TControlTracker * aControlTracker = new TControlTracker;
  1450.     aControlTracker->IControlTracker(this, theMouse);
  1451.     this->PostCommand(aControlTracker);
  1452. } // T3DRadio::DoMouseCommand
  1453.  
  1454. //-------------------------------------------------------------------------------------
  1455. // T3DRadio::TrackMouse
  1456. //-------------------------------------------------------------------------------------
  1457. #pragma segment A3DControlSelCommand
  1458.  
  1459. pascal void T3DRadio::TrackMouse(TrackPhase aTrackPhase,
  1460.                                                              VPoint& ,
  1461.                                                              // anchorPoint
  1462.                                                              VPoint& ,
  1463.                                                              // previousPoint
  1464.                                                              VPoint& nextPoint,
  1465.                                                              Boolean)                            // OVERRIDE
  1466. {
  1467.     Boolean state = false;
  1468.     
  1469.     if (!this->IsDimmed())
  1470.         switch(aTrackPhase)
  1471.         {
  1472.             case trackBegin:
  1473.                 state = fHilite;
  1474.                 this->HiliteState(TRUE, kRedraw);
  1475.                 break;
  1476.             case trackContinue:
  1477.                 if (this->ContainsMouse(nextPoint))
  1478.                     this->HiliteState(TRUE, kRedraw);
  1479.                 else
  1480.                     this->HiliteState(state, kRedraw);
  1481.                 break;
  1482.             case trackEnd:
  1483.                 if (this->ContainsMouse(nextPoint))
  1484.                 {
  1485.                     this->HiliteState(FALSE, this->IsOn());
  1486.                     this->HandleEvent(fEventNumber, this, NULL);
  1487.                 }
  1488.                 break;
  1489.         }
  1490. }    // T3DRadio::TrackMouse
  1491.  
  1492.  
  1493. //----------------------------------------------------------------------------------------
  1494. // T3DRadio::SetLongVal:
  1495. //    Override the way the control works so that we don't call the CDEF
  1496. //----------------------------------------------------------------------------------------
  1497. #pragma segment A3DControlRes
  1498.  
  1499. pascal void T3DRadio::SetLongVal(VCoordinate itsVal,
  1500.                                 Boolean /*redraw*/)
  1501. {
  1502.     itsVal = Max(fLongMin, Min(itsVal, fLongMax));
  1503.     if (itsVal != fLongVal)
  1504.     {
  1505.         fLongVal = itsVal;
  1506.         CRect tempRect;
  1507.         this->ViewToQDRect(fDrawBox, tempRect);
  1508.  
  1509. //        Make a region for the inside of the button to invalidate
  1510.         CTemporaryRegion    region;    
  1511.         InsetRect(tempRect, 1,1);
  1512.         OpenRgn();
  1513.         FrameOval(tempRect);
  1514.         CloseRgn(region);
  1515.         this->InvalidateRegion(region);
  1516.     }
  1517. } // T3DRadio::SetLongVal
  1518.  
  1519.  
  1520. //----------------------------------------------------------------------------------------
  1521. // T3DRadio::HiliteState:
  1522. //----------------------------------------------------------------------------------------
  1523. #pragma segment A3DControlNonRes
  1524.  
  1525. pascal void T3DRadio::HiliteState(Boolean state,Boolean redraw)
  1526. {
  1527.     if (state != fHilite)
  1528.     {
  1529.         fHilite = state;
  1530.         if (state)                                // hilite adorner draws the hilite state
  1531.             this->AddAdorner(gHiliteAdorner, kAdornLast - 5, kDontRedraw);
  1532.         else
  1533.             this->DeleteAdorner(gHiliteAdorner, kDontRedraw);
  1534.         if (redraw)
  1535.             this->Hilite();
  1536.     }
  1537. } // T3DRadio::HiliteState
  1538.  
  1539.  
  1540. //----------------------------------------------------------------------------------------
  1541. // T3DRadio::DimState:
  1542. //----------------------------------------------------------------------------------------
  1543. #pragma segment A3DControlNonRes
  1544.  
  1545. pascal void T3DRadio::DimState(Boolean state,
  1546.                                Boolean redraw)
  1547. {
  1548.     if (state != fDimmed)
  1549.     {
  1550.         fDimmed = state;
  1551.         if (state)                                // dim adorner draws the dim state
  1552.             this->AddAdorner(gDimAdorner, kAdornLast - 10, kDontRedraw);
  1553.         else
  1554.             this->DeleteAdorner(gDimAdorner, kDontRedraw);
  1555.         if (redraw)
  1556.             this->DrawContents();                // Draw change immediately
  1557.     }
  1558. } // T3DRadio::DimState
  1559.  
  1560.  
  1561. //-------------------------------------------------------------------------------------
  1562. // T3DRadio::Hilite
  1563. //-------------------------------------------------------------------------------------
  1564. #pragma segment A3DControlRes
  1565.  
  1566. pascal void T3DRadio::Hilite ()        // OVERRIDE
  1567. {
  1568.  
  1569.     VRect            area;
  1570.     CRect            qdArea, qdBox;
  1571.     CGraphicsState    rememberGState;
  1572.  
  1573.     #if qDebug
  1574.         this->AssumeFocused ();
  1575.     #endif
  1576.     
  1577.     this->ControlArea (area);
  1578.     this->ViewToQDRect (area, qdArea);
  1579.     this->ViewToQDRect(fDrawBox, qdBox);
  1580.  
  1581.     CPenNormal();
  1582.     if (fHilite) 
  1583.     {
  1584.         InsetRect(qdBox, 1, 1);
  1585.         FrameOval(qdBox);
  1586.         InsetRect(qdBox, 1,1);
  1587.  
  1588. //        Erase the content of the oval
  1589.         SetIfBkColor(fBackColor);    
  1590.         if (this->IsOn())
  1591.         {
  1592.             PenPat(&qd.white);
  1593.             FrameOval(qdBox);
  1594.         }
  1595.         else
  1596.             EraseOval(qdBox);
  1597.     }
  1598.     else
  1599.         this->DrawCheck();
  1600. } // T3DRadio::Hilite
  1601.  
  1602.  
  1603. //-------------------------------------------------------------------------------------
  1604. // T3DRadio::Dim
  1605. //-------------------------------------------------------------------------------------
  1606. #pragma segment ControlRes
  1607.  
  1608. pascal void T3DRadio::Dim ()        // OVERRIDE
  1609. {
  1610.     VRect             area;
  1611.     CRect             qdArea;
  1612.     CGraphicsState    rememberGState;
  1613.  
  1614.     this->ControlArea (area);
  1615.     area.left += fDrawBox.right;
  1616.     this->ViewToQDRect (area, qdArea);
  1617.  
  1618.     short pixelSize;
  1619.     CDrawPerDevice device(qdArea);
  1620.     while (device.NextDevice (pixelSize)) 
  1621.     {
  1622. //        Do the normal gray pattern thing if we're in B & W
  1623.         if (pixelSize < 2)
  1624.         {
  1625.             #if qDebug
  1626.                 this->AssumeFocused ();
  1627.             #endif
  1628.             
  1629.             InsetRect (qdArea, 1, 1);
  1630.             
  1631.             PenPat (&qd.gray);
  1632.             PenMode (patBic);
  1633.             PaintRect (qdArea);
  1634.             InsetRect (qdArea, -1, -1);
  1635.         }
  1636.     }
  1637. } // T3DRadio::Dim
  1638.  
  1639. //-------------------------------------------------------------------------------------
  1640. // T3DRadio::DrawBoxText
  1641. //-------------------------------------------------------------------------------------
  1642. #pragma segment A3DControlRes
  1643.  
  1644. pascal void T3DRadio::DrawBoxText (const CStr255& s, const CRect& box, Boolean preferOutline)
  1645. {
  1646.     FontInfo         theFontInfo;
  1647.     CRect             localBox = box;
  1648.     CRect            qdArea;
  1649.     CGraphicsState    rememberGState;
  1650.     
  1651.     CWhileOutlinePreferred setOP (preferOutline);
  1652.     
  1653.     short textHeight = MAGetFontInfo (theFontInfo);
  1654.     CPoint boxSize = localBox.GetSize ();
  1655.     
  1656. //    Center the text horizontally
  1657.     localBox.top += (boxSize.v - textHeight) / 2;
  1658.     MoveTo (localBox.left, localBox.top + theFontInfo.ascent);
  1659.     
  1660.     short pixelSize;
  1661.     CDrawPerDevice device(localBox);
  1662.     while (device.NextDevice (pixelSize)) 
  1663.     {
  1664.     //    If we're dimmed, draw in gray, else draw in the fore color
  1665.         if (pixelSize > 2)
  1666.         {    
  1667.             SetIfBkColor(fBackColor);
  1668.             if (this->IsDimmed())
  1669.                 //    Draw the text in gray if we can
  1670.                 SetIfColor(kMediumGray);
  1671.             else
  1672.                 SetIfColor(fForeColor);
  1673.         }
  1674.         MoveTo (localBox.left, localBox.top + theFontInfo.ascent);
  1675.         DrawString (s);        // This would be faster if we did StringWidth and DrawChar...
  1676.     }
  1677.     
  1678. } // T3DRadio::DrawBoxText
  1679.  
  1680.  
  1681. //-------------------------------------------------------------------------------------
  1682. // T3DRadio::DrawBox
  1683. //-------------------------------------------------------------------------------------
  1684. #pragma segment A3DControlRes
  1685.  
  1686. pascal void T3DRadio::DrawBox()
  1687. {
  1688.     CRect            qdBox;
  1689.     CGraphicsState    rememberGState;
  1690.     
  1691.     this->ViewToQDRect(fDrawBox, qdBox);
  1692.  
  1693.     short pixelSize;
  1694.     CDrawPerDevice device(qdBox);
  1695.     while (device.NextDevice (pixelSize)) 
  1696.     {
  1697.         if (pixelSize > 2) 
  1698.         {
  1699.             if (this->IsDimmed())
  1700.                 SetIfColor(kMediumGray);
  1701.             else
  1702.                 SetIfColor(fForeColor);
  1703.         }
  1704.         FrameOval(qdBox);
  1705.     }
  1706. }
  1707.  
  1708.  
  1709. //-------------------------------------------------------------------------------------
  1710. // T3DRadio::DrawCheck
  1711. //        This actually draws a dot, but I wanted to keep it similar to the check box
  1712. //-------------------------------------------------------------------------------------
  1713. #pragma segment A3DControlRes
  1714.  
  1715. pascal void T3DRadio::DrawCheck()
  1716. {
  1717.     CRect            qdBox;
  1718.     short            pixelSize;
  1719.     CGraphicsState    rememberGState;
  1720.     
  1721.     this->ViewToQDRect(fDrawBox, qdBox);
  1722.  
  1723. //    First erase the oval
  1724.     InsetRect(qdBox, 1, 1);
  1725.     if (this->IsDimmed())
  1726.         SetIfBkColor(fBackColor);
  1727.     else
  1728.         SetIfBkColor(gRGBWhite);
  1729.     EraseOval(qdBox);
  1730.     InsetRect(qdBox, -1, -1);
  1731.  
  1732. //    Check to see if we're on
  1733.     if (this->IsOn())
  1734.     {
  1735.         CDrawPerDevice device(qdBox);
  1736.         while (device.NextDevice (pixelSize)) 
  1737.         {
  1738. //                This takes some pretty subtle work
  1739.             if (pixelSize > 2) 
  1740.             {
  1741.                 if (!this->IsDimmed())
  1742.                 {
  1743.                     SetIfColor(kLightGray);
  1744.                     MoveTo(qdBox.left + 9, qdBox.top + 5);
  1745.                     LineTo(qdBox.left + 9, qdBox.top + 7);
  1746.                     MoveTo(qdBox.left + 5, qdBox.top + 9);
  1747.                     LineTo(qdBox.left + 7, qdBox.top + 9);
  1748.         
  1749.                     SetIfColor(kLightGray2);
  1750.                     MoveTo(qdBox.left + 3, qdBox.top + 9);
  1751.                     LineTo(qdBox.left + 4, qdBox.top + 9);
  1752.                     MoveTo(qdBox.left + 9, qdBox.top + 3);
  1753.                     LineTo(qdBox.left + 9, qdBox.top + 4);
  1754.         
  1755.                     SetIfColor(kLightGray4);
  1756.                     MoveTo(qdBox.left + 2, qdBox.top + 9);
  1757.                     LineTo(qdBox.left + 2, qdBox.top + 8);
  1758.                     LineTo(qdBox.left + 3, qdBox.top + 8);
  1759.                     MoveTo(qdBox.left + 8, qdBox.top + 3);
  1760.                     LineTo(qdBox.left + 8, qdBox.top + 2);
  1761.                     LineTo(qdBox.left + 9, qdBox.top + 2);
  1762.         
  1763.                     SetIfColor(kMediumLightGray);
  1764.                     MoveTo(qdBox.left + 2, qdBox.top + 7);
  1765.                     LineTo(qdBox.left + 2, qdBox.top + 4);
  1766.                     LineTo(qdBox.left + 4, qdBox.top + 2);
  1767.                     LineTo(qdBox.left + 7, qdBox.top + 2);
  1768.         
  1769.                     SetIfColor(kMediumGray);
  1770.                     MoveTo(qdBox.left + 1, qdBox.top + 7);
  1771.                     LineTo(qdBox.left + 1, qdBox.top + 4);
  1772.                     LineTo(qdBox.left + 4, qdBox.top + 1);
  1773.                     LineTo(qdBox.left + 7, qdBox.top + 1);
  1774.                     MoveTo(qdBox.left + 2, qdBox.top + 2); // this is faster
  1775.                     LineTo(qdBox.left + 2, qdBox.top + 2); // than SetCPixel
  1776.                     SetIfColor(gRGBBlack);
  1777.                 }
  1778.                 else
  1779.                     SetIfColor(kMediumGray);
  1780.             }
  1781.             else
  1782.                 SetIfColor(gRGBBlack);
  1783.             InsetRect(qdBox, 3,3);
  1784.             FillOval(qdBox, &qd.black);
  1785.             InsetRect(qdBox, -3, -3);
  1786.         }    
  1787.     }
  1788. //    This is how we look when we're off
  1789.     else
  1790.     {
  1791. //        Off and dimmed takes some work, off and not dimmed takes no work
  1792.         if (!this->IsDimmed())
  1793.         {
  1794.             CDrawPerDevice device(qdBox);
  1795.             while (device.NextDevice (pixelSize)) 
  1796.             {
  1797.                 if (pixelSize > 2) 
  1798.                 {
  1799.                     SetIfColor(kLightGray);
  1800.                     MoveTo(qdBox.left + 6, qdBox.top + 2);
  1801.                     LineTo(qdBox.left + 3, qdBox.top + 5);
  1802.                     MoveTo(qdBox.left + 4, qdBox.top + 5);
  1803.                     LineTo(qdBox.left + 7, qdBox.top + 2);
  1804.                     MoveTo(qdBox.left + 3, qdBox.top + 5);
  1805.                     LineTo(qdBox.left + 3, qdBox.top + 7);
  1806.         
  1807.                     SetIfColor(kLightGray2);
  1808.                     MoveTo(qdBox.left + 3, qdBox.top + 8);
  1809.                     LineTo(qdBox.left + 4, qdBox.top + 8);
  1810.                     LineTo(qdBox.left + 4, qdBox.top + 6);
  1811.                     LineTo(qdBox.left + 6, qdBox.top + 6);
  1812.                     LineTo(qdBox.left + 6, qdBox.top + 4);
  1813.                     LineTo(qdBox.left + 7, qdBox.top + 4);
  1814.                     LineTo(qdBox.left + 7, qdBox.top + 3);
  1815.                     LineTo(qdBox.left + 8, qdBox.top + 3);
  1816.                     LineTo(qdBox.left + 8, qdBox.top + 2);
  1817.                     MoveTo(qdBox.left + 5, qdBox.top + 5);
  1818.                     LineTo(qdBox.left + 5, qdBox.top + 5);
  1819.                     MoveTo(qdBox.left + 7, qdBox.top + 5);
  1820.                     LineTo(qdBox.left + 7, qdBox.top + 5);
  1821.                     MoveTo(qdBox.left + 5, qdBox.top + 7);
  1822.                     LineTo(qdBox.left + 5, qdBox.top + 7);
  1823.         
  1824.                     SetIfColor(kLightGray4);
  1825.                     MoveTo(qdBox.left + 3, qdBox.top + 9);
  1826.                     LineTo(qdBox.left + 5, qdBox.top + 9);
  1827.                     LineTo(qdBox.left + 5, qdBox.top + 8);
  1828.                     LineTo(qdBox.left + 6, qdBox.top + 8);
  1829.                     LineTo(qdBox.left + 6, qdBox.top + 7);
  1830.                     LineTo(qdBox.left + 7, qdBox.top + 7);
  1831.                     LineTo(qdBox.left + 7, qdBox.top + 6);
  1832.                     LineTo(qdBox.left + 8, qdBox.top + 6);
  1833.                     LineTo(qdBox.left + 8, qdBox.top + 4);
  1834.         
  1835.                     SetIfColor(kMediumLightGray);
  1836.                     MoveTo(qdBox.left + 6, qdBox.top + 9);
  1837.                     LineTo(qdBox.left + 7, qdBox.top + 9);
  1838.                     LineTo(qdBox.left + 7, qdBox.top + 8);
  1839.                     LineTo(qdBox.left + 8, qdBox.top + 8);
  1840.                     LineTo(qdBox.left + 8, qdBox.top + 7);
  1841.                     LineTo(qdBox.left + 9, qdBox.top + 7);
  1842.                     LineTo(qdBox.left + 9, qdBox.top + 2);
  1843.         
  1844.                     SetIfColor(kMediumGray);
  1845.                     MoveTo(qdBox.left + 4, qdBox.top + 10);
  1846.                     LineTo(qdBox.left + 7, qdBox.top + 10);
  1847.                     MoveTo(qdBox.left + 8, qdBox.top + 9);
  1848.                     LineTo(qdBox.left + 9, qdBox.top + 9);
  1849.                     LineTo(qdBox.left + 9, qdBox.top + 8);
  1850.                     MoveTo(qdBox.left + 10, qdBox.top + 7);
  1851.                     LineTo(qdBox.left + 10, qdBox.top + 4);
  1852.         
  1853.                 }
  1854.             }
  1855.         }
  1856.     }
  1857. }
  1858.  
  1859.  
  1860. //-------------------------------------------------------------------------------------
  1861. // T3DRadio::InstallColor
  1862. //        Override because we don't want the inherited method, which uses the CDEF
  1863. //-------------------------------------------------------------------------------------
  1864. #pragma segment A3DControlRes
  1865.  
  1866. pascal void T3DRadio::InstallColor(const CRGBColor& theColor,
  1867.                                    Boolean redraw)
  1868. {
  1869.     fForeColor = theColor;
  1870.     if (redraw)
  1871.         this->ForceRedraw();
  1872. }
  1873.  
  1874.  
  1875.  
  1876. //=====================================================================================
  1877. // CLASS:    T3DButton
  1878. //    A 3D version of our old friend the Button
  1879. //=====================================================================================
  1880.  
  1881. //-------------------------------------------------------------------------------------
  1882. // T3DButton::Initialize
  1883. //-------------------------------------------------------------------------------------
  1884. #pragma segment A3DControlOpen
  1885.  
  1886. pascal void T3DButton::Initialize ()                // OVERRIDE 
  1887. {
  1888.  
  1889.     inherited::Initialize();
  1890.     
  1891.     f3DAdorner = NULL;
  1892.     fHilitedTextColor = gRGBBlack;
  1893.  
  1894. } // T3DButton::Initialize
  1895.  
  1896.  
  1897. //-------------------------------------------------------------------------------------
  1898. // T3DButton::DoPostCreate
  1899. //-------------------------------------------------------------------------------------
  1900. #pragma segment A3DControlOpen
  1901.  
  1902. pascal void T3DButton::DoPostCreate (TDocument *itsDocument) // OVERRIDE 
  1903. {
  1904.  
  1905.     inherited::DoPostCreate (itsDocument);
  1906.     
  1907.     if (f3DAdorner == NULL)
  1908.         this->CreateButtonAdorner ();
  1909.         
  1910. } // T3DButton::DoPostCreate
  1911.  
  1912.  
  1913. //-------------------------------------------------------------------------------------
  1914. // T3DButton::I3DButton
  1915. //-------------------------------------------------------------------------------------
  1916. #pragma segment A3DControlOpen
  1917.  
  1918. pascal void T3DButton::I3DButton (TView* itsSuperView,  const VPoint& itsLocation,
  1919.                                                            const VPoint& itsSize,
  1920.                                                            SizeDeterminer itsHSizeDet,
  1921.                                                            SizeDeterminer itsVSizeDet,
  1922.                                                          const CStr255& itsLabel)
  1923. {
  1924.  
  1925.     this->IButton(itsSuperView, itsLocation, itsSize, itsHSizeDet, itsVSizeDet, itsLabel);
  1926.     
  1927.     //    • If we are being built procedurally then build the adorner
  1928.     if (f3DAdorner == NULL)
  1929.         this->CreateButtonAdorner ();
  1930.  
  1931. } // T3DButton::I3DButton
  1932.  
  1933. //-------------------------------------------------------------------------------------
  1934. // T3DButton::Clone
  1935. //-------------------------------------------------------------------------------------
  1936. #pragma segment A3DControlNonRes
  1937.  
  1938. pascal TObject* T3DButton::Clone ()                // OVERRIDE 
  1939. {
  1940.     T3DButton*    aClonedButton;
  1941.  
  1942.     aClonedButton = (T3DButton *)(inherited::Clone ());
  1943.     aClonedButton->fHilitedTextColor = fHilitedTextColor;
  1944.     aClonedButton->CreateButtonAdorner();
  1945.     
  1946.     return aClonedButton;
  1947.     
  1948. } // T3DButton::Clone
  1949.  
  1950. //-------------------------------------------------------------------------------------
  1951. // T3DButton::Free
  1952. //-------------------------------------------------------------------------------------
  1953. #pragma segment A3DControlClose
  1954.  
  1955. pascal void T3DButton::Free ()                    // OVERRIDE 
  1956. {
  1957.     inherited::Free ();
  1958.     
  1959. } // T3DButton::Free
  1960.  
  1961. //-------------------------------------------------------------------------------------
  1962. // T3DButton::DoMouseCommand
  1963. //-------------------------------------------------------------------------------------
  1964. pascal void T3DButton::DoMouseCommand(VPoint& theMouse,
  1965.                                                  TToolboxEvent* ,
  1966.                                                  CPoint)        // override 
  1967. {
  1968.     TControlTracker * aControlTracker = new TControlTracker;
  1969.     aControlTracker->IControlTracker(this, theMouse);
  1970.     this->PostCommand(aControlTracker);
  1971. } // TControl::DoMouseCommand
  1972.  
  1973. //-------------------------------------------------------------------------------------
  1974. // T3DButton::TrackMouse
  1975. //-------------------------------------------------------------------------------------
  1976. #pragma segment A3DControlSelCommand
  1977.  
  1978. pascal void T3DButton::TrackMouse(TrackPhase aTrackPhase,
  1979.                                                              VPoint& ,
  1980.                                                              // anchorPoint
  1981.                                                              VPoint& ,
  1982.                                                              // previousPoint
  1983.                                                              VPoint& nextPoint,
  1984.                                                              Boolean)                            // OVERRIDE
  1985. {
  1986.     Boolean state = false;
  1987.  
  1988.     if (!this->IsDimmed())    
  1989.         switch(aTrackPhase)
  1990.         {
  1991.             case trackBegin:
  1992.                 state = fHilite;
  1993.                 this->HiliteState(TRUE, kRedraw);
  1994.                 break;
  1995.             case trackContinue:
  1996.                 if (this->ContainsMouse(nextPoint))
  1997.                     this->HiliteState(TRUE, kRedraw);
  1998.                 else
  1999.                     this->HiliteState(state, kRedraw);
  2000.                 break;
  2001.             case trackEnd:
  2002.                 if (this->ContainsMouse(nextPoint))
  2003.                 {
  2004.                     this->HiliteState(FALSE, kRedraw);
  2005.                     this->HandleEvent(fEventNumber, this, NULL);
  2006.                 }
  2007.                 break;
  2008.         }
  2009. }    // T3DButton::TrackMouse
  2010.  
  2011. //----------------------------------------------------------------------------------------
  2012. // T3DButton::HiliteState:
  2013. //----------------------------------------------------------------------------------------
  2014. #pragma segment A3DControlNonRes
  2015.  
  2016. pascal void T3DButton::HiliteState(Boolean state,Boolean redraw)
  2017. {
  2018.     if (state != fHilite)
  2019.     {
  2020.         fHilite = state;
  2021.         if (state)                                // hilite adorner draws the hilite state
  2022.             this->AddAdorner(gHiliteAdorner, kAdornLast - 5, kDontRedraw);
  2023.         else
  2024.             this->DeleteAdorner(gHiliteAdorner, kDontRedraw);
  2025.         if (redraw && this->IsDrawable())
  2026.             this->Hilite();
  2027.     }
  2028. } // T3DButton::HiliteState
  2029.  
  2030.  
  2031. //----------------------------------------------------------------------------------------
  2032. // T3DButton::DimState:
  2033. //----------------------------------------------------------------------------------------
  2034. #pragma segment A3DControlNonRes
  2035.  
  2036. pascal void T3DButton::DimState(Boolean state,
  2037.                                Boolean redraw)
  2038. {
  2039.     if (state != fDimmed)
  2040.     {
  2041.         fDimmed = state;
  2042.         if (state)                                // dim adorner draws the dim state
  2043.             this->AddAdorner(gDimAdorner, kAdornLast - 10, kDontRedraw);
  2044.         else
  2045.             this->DeleteAdorner(gDimAdorner, kDontRedraw);
  2046.         if (redraw)
  2047.             this->DrawContents();                // Draw change immediately
  2048.     }
  2049. } // T3DButton::DimState
  2050.  
  2051. //-------------------------------------------------------------------------------------
  2052. // T3DButton::CreateButtonAdorner
  2053. //-------------------------------------------------------------------------------------
  2054. #pragma segment A3DControlOpen
  2055.  
  2056. pascal void T3DButton::CreateButtonAdorner ()
  2057. {
  2058.     
  2059.     // •    Add the Button Adorner
  2060.     T3DTextButtonAdorner* adorner = new T3DTextButtonAdorner;
  2061.     adorner->I3DTextButtonAdorner (kFreeOnDeletion);
  2062.     f3DAdorner = adorner;
  2063.     
  2064.     this->AddAdorner (adorner, kAdornFirst, kDontInvalidate);
  2065.     
  2066. } // T3DButton::CreateButtonAdorner
  2067.  
  2068. //-------------------------------------------------------------------------------------
  2069. // T3DButton::DrawBoxText
  2070. //-------------------------------------------------------------------------------------
  2071. #pragma segment A3DControlRes
  2072.  
  2073. pascal void T3DButton::DrawBoxText (    const CStr255& s,
  2074.                                                              const CRect& box,
  2075.                                                              Boolean preferOutline)
  2076. {
  2077.  
  2078.     FontInfo     theFontInfo;
  2079.     CRect         qdArea, localBox = box;
  2080.     CGraphicsState    remember;
  2081.     
  2082.     CWhileOutlinePreferred setOP (preferOutline);
  2083.     
  2084.     short textHeight = MAGetFontInfo (theFontInfo);
  2085.     CPoint boxSize = localBox.GetSize ();
  2086.     
  2087. //    Center the text in the button
  2088.     localBox.left += (boxSize.h - StringWidth (s)) / 2;
  2089.     localBox.top += (boxSize.v - textHeight) / 2;
  2090.     
  2091.     this->ViewToQDRect (localBox, qdArea);
  2092.     short    pixelSize;
  2093.     CDrawPerDevice device(qdArea);
  2094.     while (device.NextDevice (pixelSize)) 
  2095.     {
  2096.         if (pixelSize >= 4)
  2097.         {
  2098.         //    If we're non B & W and we're dimmed, draw in gray text
  2099.             if (this->IsDimmed())
  2100.                 SetIfColor(kMediumGray);
  2101.         //    If we're hilited, use the hilite text color
  2102.             else if (fHilite)
  2103.                 SetIfColor(fHilitedTextColor);
  2104.         }
  2105.         MoveTo (localBox.left, localBox.top + theFontInfo.ascent);
  2106.         DrawString (s);
  2107.     }
  2108.  
  2109. } // T3DButton::DrawBoxText
  2110.  
  2111. //-------------------------------------------------------------------------------------
  2112. // T3DButton::Draw
  2113. //-------------------------------------------------------------------------------------
  2114. #pragma segment A3DControlRes
  2115.  
  2116. pascal void T3DButton::Draw (const VRect& /*area*/)        // OVERRIDE 
  2117. {
  2118.  
  2119.     VRect         theRect;
  2120.     CRect        qdArea;
  2121.     CStr255        label;
  2122.     
  2123.     this->ControlArea (theRect);
  2124.     this->ViewToQDRect (theRect, qdArea);
  2125.     
  2126.     this->GetText (label);
  2127.             
  2128. //    Just draw the text.  The adorner takes care of the 3D stuff
  2129.     DrawBoxText (label, qdArea, FALSE);
  2130.     
  2131. } // T3DButton::Draw
  2132.  
  2133. //-------------------------------------------------------------------------------------
  2134. // T3DButton::Hilite
  2135. //-------------------------------------------------------------------------------------
  2136. #pragma segment ControlRes
  2137.  
  2138. pascal void T3DButton::Hilite ()        // OVERRIDE
  2139. {
  2140.  
  2141.     VRect            area;
  2142.     CRect            qdArea;
  2143.     CGraphicsState    rememberGState;
  2144.     
  2145.     #if qDebug
  2146.         this->AssumeFocused ();
  2147.     #endif
  2148.     
  2149.     this->ControlArea (area);
  2150.     this->ViewToQDRect (area, qdArea);
  2151.  
  2152.     short    pixelSize;
  2153.     CDrawPerDevice device(qdArea);
  2154. //    We use some funky logic here because of the way the 3d adorner works.
  2155. //  For 4, 8 and above, we draw one way.  Otherwise we draw another way
  2156. //    See the adorner code for more info
  2157.     while (device.NextDevice (pixelSize)) 
  2158.     {
  2159.         if (pixelSize < 4)
  2160.         {
  2161. //            We need to draw the text BEFORE the adorner if we're B & W
  2162.             if (fHilite)
  2163.             {
  2164.                 this->Draw (area);
  2165.                 f3DAdorner->Draw (this, area);
  2166.             }
  2167.             else
  2168.             {
  2169.                 f3DAdorner->Draw(this, area);
  2170.                 this->Draw(area);
  2171.             }
  2172.         }
  2173.         else
  2174.         {
  2175. //            We need to draw the text AFTER the adorner for better than B & W
  2176.             f3DAdorner->Draw(this, area);
  2177.             this->Draw(area);
  2178.         }
  2179.     }
  2180. } // T3DButton::Hilite
  2181.  
  2182. //-------------------------------------------------------------------------------------
  2183. // T3DButton::Dim
  2184. //-------------------------------------------------------------------------------------
  2185. #pragma segment A3DControlRes
  2186.  
  2187. pascal void T3DButton::Dim ()        // OVERRIDE
  2188. {
  2189.  
  2190.     VRect            area;
  2191.     CRect            qdArea;
  2192.     CGraphicsState     rememberGState;    
  2193.     
  2194.     #if qDebug
  2195.         this->AssumeFocused ();
  2196.     #endif
  2197.     
  2198.     this->ControlArea (area);
  2199.     this->ViewToQDRect (area, qdArea);
  2200.     InsetRect (qdArea, 1, 1);
  2201.     
  2202.     short pixelSize;
  2203.     CDrawPerDevice device(qdArea);
  2204.     while (device.NextDevice (pixelSize)) 
  2205.     {
  2206. //        The old fashioned way is to use a gray pattern to dim
  2207.         if (pixelSize < 2)
  2208.         {
  2209.             #if qDebug
  2210.                 this->AssumeFocused ();
  2211.             #endif
  2212.             
  2213.             InsetRect (qdArea, 1, 1);
  2214.             
  2215.             PenPat (&qd.gray);
  2216.             PenMode (patBic);
  2217.             PaintRect (qdArea);
  2218.             InsetRect (qdArea, -1, -1);
  2219.         }
  2220.     }
  2221.  
  2222. } // T3DButton::Dim
  2223.  
  2224.  
  2225. //=====================================================================================
  2226. // T3DTextButtonAdorner
  2227. //        This is an auxiliary adorner for T3DButtons
  2228. //=====================================================================================
  2229.  
  2230. //-------------------------------------------------------------------------------------
  2231. // T3DTextButtonAdorner::I3DTextButtonAdorner
  2232. //-------------------------------------------------------------------------------------
  2233. #pragma segment A3DControlOpen
  2234.  
  2235. pascal void T3DTextButtonAdorner::I3DTextButtonAdorner (    Boolean freeOnDeletion)
  2236. {
  2237.     //    • Call our superclass to complete initialization
  2238.     this->IAdorner (k3DTextButtonAdorner,freeOnDeletion);
  2239.     
  2240. } // T3DTextButtonAdorner::I3DTextButtonAdorner
  2241.  
  2242. //=====================================================================================
  2243. // •• DRAWING
  2244. //-------------------------------------------------------------------------------------
  2245. // T3DTextButtonAdorner::Draw
  2246. //-------------------------------------------------------------------------------------
  2247. //
  2248. //    This overridden draw method handles the drawing of the buttons border and then
  2249. //    branches to the appropriate appropriate method to draw the buttons contents, based 
  2250. //    on the bit depth of the device being drawn to.  Currently this method supports 1, 4,
  2251. //    and 8 bit or more devices.
  2252.  
  2253. #pragma segment A3DControlRes
  2254.  
  2255. pascal void T3DTextButtonAdorner::Draw (    TView* itsView, 
  2256.                                                 const VRect& /*area*/)
  2257. {
  2258.  
  2259.     VRect                theRect;
  2260.     CRect                qdArea;
  2261.     short                pixelSize;
  2262.     CRGBColor            color;
  2263.     
  2264.     //    • Instantiate a stack based object that saves our graphic state
  2265.     CGraphicsState aGraphicsState;
  2266.     
  2267.     //    •    Coerce the view to a control and then get its QD area
  2268.     TControl* theControl = (TControl*)itsView;    
  2269.     theControl->ControlArea (theRect);
  2270.     theControl->ViewToQDRect (theRect, qdArea);
  2271.         
  2272.     //    • Instantiate the stack based object that handles the per device clipping
  2273.     //    the area is passed in so that the object can do clipping from it
  2274.     CDrawPerDevice device (qdArea);
  2275.     
  2276.     //    • We will cycle through all of the devices, drawing will be handle based on
  2277.     //    the pixel size for each device
  2278.     while (device.NextDevice (pixelSize)) 
  2279.     {
  2280.         
  2281.         //    • Draw the button with full colors         
  2282.         if (pixelSize >= 8) 
  2283.         {
  2284.             //    • First step is to setup the appropriate gray fill color
  2285.             if (theControl->fHilite)
  2286.                 color = kMediumGray;
  2287.             else if (((TButton *)itsView)->IsDimmed())
  2288.                 color = kLightGray;
  2289.             else
  2290.                 color = kLightGray2;
  2291.         
  2292.             //    • Fill the round rect with the color
  2293.             SetIfColor (color);
  2294.             PaintRoundRect (qdArea, kOvalWidth, kOvalHeight);
  2295.  
  2296.             //    • Frame button with a black border or gray if it's dimmed
  2297.             if (((TButton *)itsView)->IsDimmed())
  2298.                 SetIfColor(kMediumGray);
  2299.             else
  2300.                 SetIfColor (gRGBBlack);
  2301.             this->Frame (qdArea);
  2302.             
  2303.             //    • Inset the area in preparartion for the drawing of the buttons content
  2304.             InsetRect (qdArea, 1, 1);
  2305.         
  2306.             //    • Draw the button assuming 8 bit or better color
  2307.             //         But don't draw any 3D if we're dimmed
  2308.             if (!((TButton *)itsView)->IsDimmed())
  2309.                 this->Draw8Bit (qdArea, theControl->fHilite);
  2310.  
  2311.             InsetRect (qdArea, -1, -1);
  2312.             
  2313.         }
  2314.         else if (pixelSize == 4)    //    • Draw with only 16 colors
  2315.         {
  2316.         
  2317.             //    • First step is to setup the appropriate gray fill color
  2318.             if (theControl->fHilite)
  2319.                 SetRGBColor (color, kRGB4BitGray2, kRGB4BitGray2, kRGB4BitGray2);
  2320.             else if (((TButton *)itsView)->IsDimmed())
  2321.                 color = kLightGray;
  2322.             else
  2323.                 SetRGBColor (color, kRGB4BitGray1, kRGB4BitGray1, kRGB4BitGray1);
  2324.         
  2325.             //    • Fill the round rect with the color
  2326.             SetIfColor (color);
  2327.             PaintRoundRect (qdArea, kOvalWidth, kOvalHeight);
  2328.  
  2329.             //    • Frame button with a black border or gray if we're dimmed
  2330.             if (((TButton *)itsView)->IsDimmed())
  2331.                 SetIfColor(kMediumGray);
  2332.             else
  2333.                 SetIfColor (gRGBBlack);
  2334.             this->Frame (qdArea);
  2335.             
  2336.             //    • Inset the area in preparartion for the drawing of the buttons content
  2337.             InsetRect (qdArea, 1, 1);
  2338.         
  2339.             //    • For now we will draw the 1 bit style for 4 bit, but this should be
  2340.             //    replaced with a 4 bit algorithm which will give you 3 shades of gray
  2341.             //         But don't draw any 3D if we're dimmed
  2342.             if (!((TButton *)itsView)->IsDimmed())
  2343.                 this->Draw4Bit (qdArea, theControl->fHilite);
  2344.  
  2345.             InsetRect (qdArea, -1, -1);
  2346.             
  2347.         }            
  2348.         else if (pixelSize < 4)    //    • Draw with 4 colors or less (no grays)
  2349.         {
  2350.             //    • We are hiliting so we need to invert the whole thing
  2351.             if  (theControl->fHilite) 
  2352.             {
  2353.                 //    • First we paint the inside white
  2354.                 InvertRoundRect (qdArea, kOvalWidth, kOvalHeight);
  2355.     
  2356.                 //    • Frame button with a black border 
  2357.                 SetIfColor (gRGBBlack);
  2358.                 this->Frame (qdArea);
  2359.             }    
  2360.             else
  2361.             {
  2362.                 //    • First we erase the entire area
  2363.                 SetIfBkColor (gRGBWhite);
  2364.                 EraseRoundRect (qdArea, kOvalWidth, kOvalHeight);
  2365.     
  2366.                 //    • Frame button with a black border 
  2367.                 SetIfColor (gRGBBlack);
  2368.                 this->Frame (qdArea);
  2369.             }
  2370.         }            
  2371.     }
  2372.         
  2373. } // T3DTextButtonAdorner::Draw
  2374.  
  2375. //=====================================================================================
  2376. // •• PRIVATE DRAWING
  2377. //-------------------------------------------------------------------------------------
  2378. // T3DTextButtonAdorner::Draw8Bit
  2379. //-------------------------------------------------------------------------------------
  2380. #pragma segment A3DControlRes
  2381.  
  2382. pascal void T3DTextButtonAdorner::Draw8Bit (const CRect& rect,
  2383.                                                     Boolean hilite)
  2384. {
  2385.     CRect             insetArea;
  2386.     CRect             controlArea;
  2387.     CRGBColor         color;
  2388.     CRGBColor         light;
  2389.     CRGBColor         dark;
  2390.  
  2391.     //    • Make a copy of the rect passed in
  2392.     controlArea = rect;
  2393.     
  2394.     //    • Save off the area passed in
  2395.     insetArea = rect;
  2396.  
  2397.     //    • Draw the hilited button
  2398.     if (hilite) 
  2399.     {    
  2400.  
  2401.         //    • Outside edge of left top shadow
  2402.         SetRGBColor (color, kRGB8BitGray9, kRGB8BitGray9, kRGB8BitGray9);
  2403.         SetIfColor (color);
  2404.         MoveTo (controlArea.left, controlArea.bottom - 3);
  2405.         LineTo (controlArea.left, controlArea.top + 2);
  2406.         MoveTo (controlArea.left + 2, controlArea.top);
  2407.         LineTo (controlArea.right - 3, controlArea.top);
  2408.  
  2409.         //    • Outside edge of bottom right shadow
  2410.         SetRGBColor (color, kRGB8BitGray3, kRGB8BitGray3, kRGB8BitGray3);
  2411.         SetIfColor (color);
  2412.         MoveTo (controlArea.left + 2, controlArea.bottom - 1);
  2413.         LineTo (controlArea.right - 3, controlArea.bottom - 1);
  2414.         MoveTo (controlArea.right - 1, controlArea.bottom - 3);
  2415.         LineTo (controlArea.right - 1, controlArea.top + 2);
  2416.         
  2417.         //    • Inset our rectangle as we move to the next level
  2418.         InsetRect (controlArea, 1, 1);
  2419.         
  2420.         //    • Inside edge of left top shadow
  2421.         SetRGBColor (color, kRGB8BitGray8, kRGB8BitGray8, kRGB8BitGray8);
  2422.         SetIfColor (color);
  2423.         MoveTo (controlArea.left, controlArea.bottom - 2);
  2424.         LineTo (controlArea.left, controlArea.top + 1);
  2425.         MoveTo (controlArea.left + 1, controlArea.top);
  2426.         LineTo (controlArea.right - 2, controlArea.top);
  2427.  
  2428.         //    • Inside edge of bottom right shadow
  2429.         color = kMediumLightGray;
  2430.         SetIfColor (color);
  2431.         MoveTo (controlArea.left + 1, controlArea.bottom - 1);
  2432.         LineTo (controlArea.right - 2, controlArea.bottom - 1);
  2433.         MoveTo (controlArea.right - 1, controlArea.bottom - 2);
  2434.         LineTo (controlArea.right - 1, controlArea.top + 1);
  2435.         
  2436.         //    •• Now draw the corners 
  2437.         //    •    TopLeft 1
  2438.         SetRGBColor (light, kRGB8BitGray8, kRGB8BitGray8, kRGB8BitGray8);
  2439.         SetRGBColor (dark, kRGB8BitGray9, kRGB8BitGray9, kRGB8BitGray9);
  2440.         this->TopLeftCorner (insetArea, light, dark, hilite);
  2441.         
  2442.         //    • TopRight 2
  2443.         SetRGBColor (light, kRGB8BitGray8, kRGB8BitGray8, kRGB8BitGray8);
  2444.         SetRGBColor (dark, kRGB8BitGray9, kRGB8BitGray9, kRGB8BitGray9);
  2445.         this->TopRightCorner (insetArea, light, dark, hilite);
  2446.         
  2447.         //    • BotLeft 3
  2448.         //    • Colors same as previous corner
  2449.         this->BotLeftCorner (insetArea, light, dark, hilite);
  2450.         
  2451.         //    • BotRight 4
  2452.         SetRGBColor (light, kRGB8BitGray3, kRGB8BitGray3, kRGB8BitGray3);
  2453.         dark = kMediumLightGray;
  2454.         this->BotRightCorner (insetArea, light, dark, hilite);
  2455.         
  2456.     }
  2457.     else //    • Draw the unhilited button
  2458.     {
  2459.         
  2460.         //    • Outside edge of bottom right shadow
  2461.         SetRGBColor (color, kRGB8BitGray8, kRGB8BitGray8, kRGB8BitGray8);
  2462.         SetIfColor (color);
  2463.         MoveTo (controlArea.left + 2, controlArea.bottom - 1);
  2464.         LineTo (controlArea.right - 3, controlArea.bottom - 1);
  2465.         MoveTo (controlArea.right - 1, controlArea.bottom - 3);
  2466.         LineTo (controlArea.right - 1, controlArea.top + 2);
  2467.         
  2468.         //    • Inset our rectangle as we move to the next level
  2469.         InsetRect (controlArea, 1, 1);
  2470.         
  2471.         //    • Light on edge of button - light source edge
  2472.         SetIfColor (gRGBWhite);
  2473.         MoveTo (controlArea.left, controlArea.bottom - 2);
  2474.         LineTo (controlArea.left, controlArea.top + 1);
  2475.         MoveTo (controlArea.left + 1, controlArea.top);
  2476.         LineTo (controlArea.right - 2, controlArea.top);
  2477.  
  2478.         //    • Inside edge of bottom right shadow
  2479.         color = kMediumGray;
  2480.         SetIfColor (color);
  2481.         MoveTo (controlArea.left + 1, controlArea.bottom - 1);
  2482.         LineTo (controlArea.right - 2, controlArea.bottom - 1);
  2483.         MoveTo (controlArea.right - 1, controlArea.bottom - 2);
  2484.         LineTo (controlArea.right - 1, controlArea.top + 1);
  2485.         
  2486.         //    •• Now draw the corners 
  2487.         //    •    TopLeft 1
  2488.         this->TopLeftCorner (insetArea, gRGBWhite, gRGBWhite, hilite);
  2489.         
  2490.         //    • TopRight 2
  2491.         light = kLightGray4;
  2492.         this->TopRightCorner (insetArea, light, light, hilite);
  2493.         
  2494.         //    • BotLeft 3
  2495.         //    • Colors same as previous corner
  2496.         this->BotLeftCorner (insetArea, light, light, hilite);
  2497.         
  2498.         //    • BotRight 4
  2499.         light = kMediumGray;
  2500.         SetRGBColor (dark, kRGB8BitGray8, kRGB8BitGray8, kRGB8BitGray8);
  2501.         this->BotRightCorner (insetArea, light, dark, hilite);
  2502.         
  2503.     }
  2504.  
  2505.  
  2506. } // T3DTextButtonAdorner::Draw8Bit
  2507.  
  2508. //-------------------------------------------------------------------------------------
  2509. // T3DTextButtonAdorner::Draw4Bit
  2510. //-------------------------------------------------------------------------------------
  2511. #pragma segment A3DControlRes
  2512.  
  2513. pascal void T3DTextButtonAdorner::Draw4Bit (const CRect& rect,
  2514.                                                     Boolean hilite)
  2515. {
  2516.     CRect             insetArea;
  2517.     CRect             controlArea;
  2518.     CRGBColor         color;
  2519.     CRGBColor         light;
  2520.     CRGBColor         dark;
  2521.  
  2522.     //    • Make a copy of the rect passed in
  2523.     controlArea = rect;
  2524.     
  2525.     //    • Save off the area passed in
  2526.     insetArea = rect;
  2527.  
  2528.     //    • Draw the hilited button
  2529.     if (hilite) 
  2530.     {    
  2531.  
  2532.         //    • Outside edge of left top shadow
  2533.         SetRGBColor (color, kRGB4BitGray3, kRGB4BitGray3, kRGB4BitGray3);
  2534.         SetIfColor (color);
  2535.         MoveTo (controlArea.left, controlArea.bottom - 3);
  2536.         LineTo (controlArea.left, controlArea.top + 2);
  2537.         MoveTo (controlArea.left + 2, controlArea.top);
  2538.         LineTo (controlArea.right - 3, controlArea.top);
  2539.  
  2540.         //    • Outside edge of bottom right shadow
  2541.         SetRGBColor (color, kRGB4BitGray1, kRGB4BitGray1, kRGB4BitGray1);
  2542.         SetIfColor (color);
  2543.         MoveTo (controlArea.left + 2, controlArea.bottom - 1);
  2544.         LineTo (controlArea.right - 3, controlArea.bottom - 1);
  2545.         MoveTo (controlArea.right - 1, controlArea.bottom - 3);
  2546.         LineTo (controlArea.right - 1, controlArea.top + 2);
  2547.         
  2548.         //    • Inset our rectangle as we move to the next level
  2549.         InsetRect (controlArea, 1, 1);
  2550.         
  2551.         //    • Inside edge of left top shadow
  2552.         SetRGBColor (color, kRGB4BitGray3, kRGB4BitGray3, kRGB4BitGray3);
  2553.         SetIfColor (color);
  2554.         MoveTo (controlArea.left, controlArea.bottom - 2);
  2555.         LineTo (controlArea.left, controlArea.top + 1);
  2556.         MoveTo (controlArea.left + 1, controlArea.top);
  2557.         LineTo (controlArea.right - 2, controlArea.top);
  2558.  
  2559.         //    • Inside edge of bottom right shadow
  2560.         SetRGBColor (color, kRGB4BitGray1, kRGB4BitGray1, kRGB4BitGray1);
  2561.         SetIfColor (color);
  2562.         MoveTo (controlArea.left + 1, controlArea.bottom - 1);
  2563.         LineTo (controlArea.right - 2, controlArea.bottom - 1);
  2564.         MoveTo (controlArea.right - 1, controlArea.bottom - 2);
  2565.         LineTo (controlArea.right - 1, controlArea.top + 1);
  2566.         
  2567.         //    •• Now draw the corners 
  2568.         //    •    TopLeft 1
  2569.         SetRGBColor (light, kRGB4BitGray3, kRGB4BitGray3, kRGB4BitGray3);
  2570.         SetRGBColor (dark, kRGB4BitGray3, kRGB4BitGray3, kRGB4BitGray3);
  2571.         this->TopLeftCorner (insetArea, light, dark, hilite);
  2572.         
  2573.         //    • TopRight 2
  2574.         SetRGBColor (light, kRGB4BitGray3, kRGB4BitGray3, kRGB4BitGray3);
  2575.         SetRGBColor (dark, kRGB4BitGray3, kRGB4BitGray3, kRGB4BitGray3);
  2576.         this->TopRightCorner (insetArea, light, dark, hilite);
  2577.         
  2578.         //    • BotLeft 3
  2579.         //    • Colors same as previous corner
  2580.         this->BotLeftCorner (insetArea, light, dark, hilite);
  2581.         
  2582.         //    • BotRight 4
  2583.         SetRGBColor (light, kRGB4BitGray1, kRGB4BitGray1, kRGB4BitGray1);
  2584.         SetRGBColor (dark, kRGB4BitGray1, kRGB4BitGray1, kRGB4BitGray1);
  2585.         this->BotRightCorner (insetArea, light, dark, hilite);
  2586.         
  2587.     }
  2588.     else //    • Draw the unhilited button
  2589.     {
  2590.         
  2591.         //    • Outside edge of bottom right shadow
  2592.         SetRGBColor (color, kRGB4BitGray3, kRGB4BitGray3, kRGB4BitGray3);
  2593.         SetIfColor (color);
  2594.         MoveTo (controlArea.left + 2, controlArea.bottom - 1);
  2595.         LineTo (controlArea.right - 3, controlArea.bottom - 1);
  2596.         MoveTo (controlArea.right - 1, controlArea.bottom - 3);
  2597.         LineTo (controlArea.right - 1, controlArea.top + 2);
  2598.         
  2599.         //    • Inset our rectangle as we move to the next level
  2600.         InsetRect (controlArea, 1, 1);
  2601.         
  2602.         //    • Light on edge of button - light source edge
  2603.         SetIfColor (gRGBWhite);
  2604.         MoveTo (controlArea.left, controlArea.bottom - 2);
  2605.         LineTo (controlArea.left, controlArea.top + 1);
  2606.         MoveTo (controlArea.left + 1, controlArea.top);
  2607.         LineTo (controlArea.right - 2, controlArea.top);
  2608.  
  2609.         //    • Inside edge of bottom right shadow
  2610.         SetRGBColor (color, kRGB4BitGray2, kRGB4BitGray2, kRGB4BitGray2);
  2611.         SetIfColor (color);
  2612.         MoveTo (controlArea.left + 1, controlArea.bottom - 1);
  2613.         LineTo (controlArea.right - 2, controlArea.bottom - 1);
  2614.         MoveTo (controlArea.right - 1, controlArea.bottom - 2);
  2615.         LineTo (controlArea.right - 1, controlArea.top + 1);
  2616.         
  2617.         //    •• Now draw the corners 
  2618.         //    •    TopLeft 1
  2619.         this->TopLeftCorner (insetArea, gRGBWhite, gRGBWhite, hilite);
  2620.         
  2621.         //    • TopRight 2
  2622.         SetRGBColor (light, kRGB4BitGray2, kRGB4BitGray2, kRGB4BitGray2);
  2623.         this->TopRightCorner (insetArea, light, light, hilite);
  2624.         
  2625.         //    • BotLeft 3
  2626.         //    • Colors same as previous corner
  2627.         this->BotLeftCorner (insetArea, light, light, hilite);
  2628.         
  2629.         //    • BotRight 4
  2630.         SetRGBColor (light, kRGB4BitGray2, kRGB4BitGray2, kRGB4BitGray2);
  2631.         SetRGBColor (dark, kRGB4BitGray3, kRGB4BitGray3, kRGB4BitGray3);
  2632.         this->BotRightCorner (insetArea, light, dark, hilite);
  2633.         
  2634.     }
  2635.  
  2636.  
  2637. } // T3DTextButtonAdorner::Draw4Bit
  2638.  
  2639. //-------------------------------------------------------------------------------------
  2640. // T3DTextButtonAdorner::Draw1Bit
  2641. //    This routine is actually not called
  2642. //-------------------------------------------------------------------------------------
  2643. #pragma segment A3DControlRes
  2644.  
  2645. pascal void T3DTextButtonAdorner::Draw1Bit (    const CRect& /*rect */,
  2646.                                                         Boolean /*hilite*/)
  2647. {
  2648. //    We don't actually use this now
  2649.  
  2650. } // T3DTextButtonAdorner::Draw1Bit
  2651.  
  2652. //=====================================================================================
  2653. // •• BUTTON FRAME
  2654. //-------------------------------------------------------------------------------------
  2655. // T3DTextButtonAdorner::Frame
  2656. //-------------------------------------------------------------------------------------
  2657. #pragma segment A3DControlRes
  2658.  
  2659. pascal void T3DTextButtonAdorner::Frame (const CRect& rect)
  2660. {
  2661.     //    •    Draw the frame around the button this never changes
  2662.     FrameRoundRect (rect, kOvalWidth, kOvalHeight);
  2663.  
  2664. } // T3DTextButtonAdorner::Frame
  2665.  
  2666. //=====================================================================================
  2667. // •• CORNER DRAWING
  2668. //-------------------------------------------------------------------------------------
  2669. // T3DTextButtonAdorner::TopLeftCorner
  2670. //-------------------------------------------------------------------------------------
  2671. #pragma segment A3DControlRes
  2672.  
  2673. pascal void T3DTextButtonAdorner::TopLeftCorner (const CRect& rect,
  2674.                                                             const CRGBColor light,
  2675.                                                             const CRGBColor dark,
  2676.                                                             Boolean hilite )
  2677. {
  2678.     if (hilite)
  2679.     {
  2680.         //    • Set the outer corner pixel
  2681.         SetIfColor(dark);
  2682.         MoveTo(rect.left + 1, rect.top + 1);
  2683.         LineTo(rect.left + 1, rect.top + 1);
  2684.         
  2685.         //    • Set the inner corner pixel
  2686.         SetIfColor(light);
  2687.         MoveTo(rect.left + 2, rect.top + 2);
  2688.         LineTo(rect.left + 2, rect.top + 2);
  2689.     }
  2690.     else
  2691.     {
  2692.         //    • Set the outer corner pixel
  2693.         SetIfColor(light);
  2694.         MoveTo(rect.left + 1, rect.top + 1);
  2695.         LineTo(rect.left + 1, rect.top + 1);
  2696.         
  2697.         //    • Set the inner corner pixel
  2698.         SetIfColor(dark);
  2699.         MoveTo(rect.left + 2, rect.top + 2);
  2700.         LineTo(rect.left + 2, rect.top + 2);
  2701.     }
  2702.     
  2703. } // T3DTextButtonAdorner::TopLeftCorner
  2704.  
  2705. //-------------------------------------------------------------------------------------
  2706. // T3DTextButtonAdorner::TopRightCorner
  2707. //-------------------------------------------------------------------------------------
  2708. #pragma segment A3DControlRes
  2709.  
  2710. pascal void T3DTextButtonAdorner::TopRightCorner (    const CRect& rect,
  2711.                                                                 const CRGBColor light,
  2712.                                                                 const CRGBColor dark,
  2713.                                                                 Boolean hilite )
  2714. {
  2715.     if (hilite)
  2716.     {
  2717.         //    • Set the outer corner pixel
  2718.         SetIfColor(dark);
  2719.         MoveTo(rect.right - 2, rect.top + 1);
  2720.         LineTo(rect.right - 2, rect.top + 1);
  2721.         
  2722.         //    • Set the inner corner pixel
  2723.         SetIfColor(light);
  2724.         MoveTo(rect.right - 3, rect.top + 2);
  2725.         LineTo(rect.right - 3, rect.top + 2);
  2726.     }
  2727.     else
  2728.     {
  2729.         //    • Set the outer corner pixel
  2730.         SetIfColor(light);
  2731.         MoveTo(rect.right - 2, rect.top + 1);
  2732.         LineTo(rect.right - 2, rect.top + 1);
  2733.         
  2734.         //    • Set the inner corner pixel
  2735.         SetIfColor(dark);
  2736.         MoveTo(rect.right - 3, rect.top + 2);
  2737.         LineTo(rect.right - 3, rect.top + 2);
  2738.     }
  2739.     
  2740. } // T3DTextButtonAdorner::TopRightCorner
  2741.  
  2742. //-------------------------------------------------------------------------------------
  2743. // T3DTextButtonAdorner::BotLeftCorner
  2744. //-------------------------------------------------------------------------------------
  2745. #pragma segment A3DControlRes
  2746.  
  2747. pascal void T3DTextButtonAdorner::BotLeftCorner (    const CRect& rect,
  2748.                                                                 const CRGBColor light,
  2749.                                                                 const CRGBColor dark,
  2750.                                                                 Boolean hilite )
  2751. {
  2752.     if (hilite)
  2753.     {
  2754.         //    • Set the outer corner pixel
  2755.         SetIfColor(dark);
  2756.         MoveTo(rect.left + 1, rect.bottom - 2);
  2757.         LineTo(rect.left + 1, rect.bottom - 2);
  2758.         
  2759.         //    • Set the inner corner pixel
  2760.         SetIfColor(light);
  2761.         MoveTo(rect.left + 2, rect.bottom - 3);
  2762.         LineTo(rect.left + 2, rect.bottom - 3);
  2763.     }
  2764.     else
  2765.     {
  2766.         //    • Set the outer corner pixel
  2767.         SetIfColor(light);
  2768.         MoveTo(rect.left + 1, rect.bottom - 2);
  2769.         LineTo(rect.left + 1, rect.bottom - 2);
  2770.         
  2771.         //    • Set the inner corner pixel
  2772.         SetIfColor(dark);
  2773.         MoveTo(rect.left + 2, rect.bottom - 3);
  2774.         LineTo(rect.left + 2, rect.bottom - 3);
  2775.     }
  2776. } // T3DTextButtonAdorner::BotLeftCorner
  2777.  
  2778. //-------------------------------------------------------------------------------------
  2779. // T3DTextButtonAdorner::BotRightCorner
  2780. //-------------------------------------------------------------------------------------
  2781. #pragma segment A3DControlRes
  2782.  
  2783. pascal void T3DTextButtonAdorner::BotRightCorner (const CRect& rect,
  2784.                                                             const CRGBColor light,
  2785.                                                             const CRGBColor dark,
  2786.                                                             Boolean hilite)
  2787. {
  2788.     if (hilite)
  2789.     {
  2790.         //    • Set the outer corner pixel
  2791.         SetIfColor(light);
  2792.         MoveTo(rect.right - 2, rect.bottom - 2);
  2793.         LineTo(rect.right - 2, rect.bottom - 2);
  2794.         
  2795.         //    • Set the inner corner pixel
  2796.         SetIfColor(dark);
  2797.         MoveTo(rect.right - 3, rect.bottom - 3);
  2798.         LineTo(rect.right - 3, rect.bottom - 3);
  2799.     }
  2800.     else
  2801.     {
  2802.         //    • Set the outer corner pixel
  2803.         SetIfColor(dark);
  2804.         MoveTo(rect.right - 2, rect.bottom - 2);
  2805.         LineTo(rect.right - 2, rect.bottom - 2);
  2806.         
  2807.         //    • Set the inner corner pixel
  2808.         SetIfColor(light);
  2809.         MoveTo(rect.right - 3, rect.bottom - 3);
  2810.         LineTo(rect.right - 3, rect.bottom - 3);
  2811.     }
  2812.     
  2813. } // T3DTextButtonAdorner::BotRightCorner
  2814.  
  2815.  
  2816.  
  2817. //===================================================================================== 
  2818. //    ••••••••••••••••• 3DIconButton class and auxiliary adorner ••••••••••••••••••••••••
  2819. //===================================================================================== 
  2820.  
  2821. //=====================================================================================
  2822. // T3DIconAdorner
  2823. //        This is an auxiliary adorner for T3DIconButtons
  2824. //=====================================================================================
  2825.  
  2826. //-------------------------------------------------------------------------------------
  2827. // T3DIconAdorner::I3DIconAdorner
  2828. //-------------------------------------------------------------------------------------
  2829. #pragma segment A3DControlOpen
  2830.  
  2831. pascal void T3DIconAdorner::I3DIconAdorner (    Boolean freeOnDeletion )
  2832. {
  2833.     //    • Call our superclass to complete initialization
  2834.     this->IAdorner ( k3DIconAdorner,freeOnDeletion );
  2835.     
  2836. } // T3DIconAdorner::I3DIconAdorner
  2837.  
  2838. //=====================================================================================
  2839. // •• DRAWING
  2840. //-------------------------------------------------------------------------------------
  2841. // T3DIconAdorner::Draw
  2842. //-------------------------------------------------------------------------------------
  2843. //
  2844. //    This overridden draw method handles the drawing of the buttons border and then
  2845. //    branches to the appropriate appropriate method to draw the buttons contents, based 
  2846. //    on the bit depth of the device being drawn to.  Currently this method supports 1, 4,
  2847. //    and 8 bit or more devices.
  2848.  
  2849. #pragma segment A3DControlRes
  2850.  
  2851. pascal void T3DIconAdorner::Draw (     TView* itsView, 
  2852.                                                 const VRect& /*area*/ )
  2853. {
  2854.  
  2855.     VRect                theRect;
  2856.     CRect                qdArea;
  2857.     short                pixelSize;
  2858.     
  2859.     //    • Instantiate a stack based object that saves our graphic state
  2860.     CGraphicsState aGraphicsState;
  2861.     
  2862.     //    •    Coerce the view to a control and then get its QD area
  2863.     TControl* theControl = (TControl*)itsView;    
  2864.     theControl->ControlArea ( theRect );
  2865.     theControl->ViewToQDRect ( theRect, qdArea );
  2866.         
  2867.     //    • Frame button with a black border that has a pixel missing in each corner
  2868.     //    this is drawn outside the while loop because it is always in black & white
  2869.     if (((TControl *)itsView)->IsDimmed())
  2870.         SetIfColor(kMediumGray);
  2871.     else
  2872.         SetIfColor ( gRGBBlack );
  2873.     this->Frame ( qdArea );
  2874.     
  2875.     //    • Inset the area in preparartion for the drawing of the buttons content
  2876.     InsetRect ( qdArea, 1, 1 );
  2877.         
  2878.     //    • Instantiate the stack based object that handles the per device clipping
  2879.     //    the area is passed in so that the object can do clipping from it
  2880.     if (((TControl *)itsView)->IsDimmed())
  2881.     {
  2882. //        Hack for non-CQD
  2883.         CDrawPerDevice device ( qdArea );
  2884.         while ( device.NextDevice ( pixelSize ) ) 
  2885.         {
  2886.             if ( pixelSize < 4 ) 
  2887.             {
  2888. //                Redraw the frame because it didn't draw if we're in non-CQD
  2889.                 CRect tempArea = qdArea;
  2890.                 CPenNormal();
  2891.                 InsetRect(tempArea, -1, -1);
  2892.                 this->Frame ( tempArea );
  2893.             }
  2894.         }
  2895.     }
  2896.     else
  2897.     {
  2898.         CDrawPerDevice device ( qdArea );
  2899.         
  2900.         //    • We will cycle through all of the devices, drawing will be handle based on
  2901.         //    the pixel size for each device
  2902.         while ( device.NextDevice ( pixelSize ) ) 
  2903.         {
  2904.             
  2905.             //    • Draw the button with full colors - there should really be two levels of 
  2906.             //    drawing here, one for 4 bit color and one for 8 bit.        
  2907.             if ( pixelSize >= 8 ) 
  2908.             {
  2909.                 
  2910.                 //    • Draw the button assuming 8 bit or better color
  2911.                 this->Draw8Bit ( qdArea, theControl->fHilite );
  2912.                 
  2913.             }
  2914.             else if ( pixelSize == 4 )    //    • Draw with only 16 colors
  2915.             {
  2916.             
  2917.                 //    • For now we will draw the 1 bit style for 4 bit, but this should be
  2918.                 //    replaced with a 4 bit algorithm which will give you 3 shades of gray
  2919.                 this->Draw4Bit ( qdArea, theControl->fHilite );
  2920.                 
  2921.             }            
  2922.             else if ( pixelSize < 4 )    //    • Draw with 4 colors or less (no grays)
  2923.             {
  2924.                 //    • Draw the 1 bit style for anything under 4 bit
  2925.                 this->Draw1Bit ( qdArea, theControl->fHilite );
  2926.                 
  2927.             }            
  2928.         }
  2929.     }
  2930.  
  2931. } // T3DIconAdorner::Draw
  2932.  
  2933.  
  2934. //=====================================================================================
  2935. // •• PRIVATE DRAWING
  2936. //-------------------------------------------------------------------------------------
  2937. // T3DIconAdorner::Draw8Bit
  2938. //-------------------------------------------------------------------------------------
  2939. #pragma segment A3DControlRes
  2940.  
  2941. pascal void T3DIconAdorner::Draw8Bit ( const CRect& rect,
  2942.                                                     Boolean hilite )
  2943. {
  2944.     CRect             insetArea;
  2945.     CRect             controlArea;
  2946.     CRGBColor         color;
  2947.     CRGBColor         light;
  2948.     CRGBColor         dark;
  2949.  
  2950.     //    • Make a copy of the rect passed in
  2951.     controlArea = rect;
  2952.     
  2953.     //    • Save off the area passed in
  2954.     insetArea = rect;
  2955.  
  2956.     //    • Draw the hilited button
  2957.     if ( hilite ) 
  2958.     {    
  2959.  
  2960.         //    • Outside edge of left top shadow
  2961.         SetRGBColor ( color, kRGB8BitGray9, kRGB8BitGray9, kRGB8BitGray9 );
  2962.         SetIfColor ( color );
  2963.         this->TopLeftSide ( controlArea );
  2964.  
  2965.         //    • Outside edge of bottom right shadow
  2966.         SetRGBColor ( color, kRGB8BitGray3, kRGB8BitGray3, kRGB8BitGray3 );
  2967.         SetIfColor ( color );
  2968.         this->BotRightSide ( controlArea );
  2969.         
  2970.         //    • Inset our rectangle as we move to the next level
  2971.         InsetRect ( controlArea, 1, 1 );
  2972.         
  2973.         //    • Inside edge of left top shadow
  2974.         SetRGBColor ( color, kRGB8BitGray8, kRGB8BitGray8, kRGB8BitGray8 );
  2975.         SetIfColor ( color );
  2976.         this->TopLeftSide ( controlArea );
  2977.  
  2978.         //    • Inside edge of bottom right shadow
  2979.         color = kMediumLightGray;
  2980.         SetIfColor ( color );
  2981.         this->BotRightSide ( controlArea );    
  2982.         
  2983.         //    •• Now draw the corners 
  2984.         //    •    TopLeft 1
  2985.         SetRGBColor ( light, kRGB8BitGray9, kRGB8BitGray9, kRGB8BitGray9 );
  2986.         SetRGBColor ( dark, kRGB8BitGray10, kRGB8BitGray10, kRGB8BitGray10 );
  2987.         this->TopLeftCorner ( insetArea, light, dark );
  2988.         
  2989.         //    • TopRight 2
  2990.         light = kMediumGray;
  2991.         SetRGBColor ( dark, kRGB8BitGray7, kRGB8BitGray7, kRGB8BitGray7 );
  2992.         this->TopRightCorner ( insetArea, light, dark );
  2993.         
  2994.         //    • BotLeft 3
  2995.         //    • Colors same as previous corner
  2996.         this->BotLeftCorner ( insetArea, light, dark );
  2997.         
  2998.         //    • BotRight 4
  2999.         light = kLightGray2;
  3000.         SetRGBColor ( dark, kRGB8BitGray3, kRGB8BitGray3, kRGB8BitGray3 );
  3001.         this->BotRightCorner ( insetArea, light, dark, hilite );
  3002.         
  3003.         //    • Setup fill color for buttons face - hilite
  3004.         color = kMediumGray;
  3005.         
  3006.     }
  3007.     else //    • Draw the unhilited button
  3008.     {
  3009.         //    • Outside edge of left top shadow
  3010.         color = kLightGray2;
  3011.         SetIfColor ( color );
  3012.         this->TopLeftSide ( controlArea );
  3013.  
  3014.         //    • Outside edge of bottom right shadow
  3015.         SetRGBColor ( color, kRGB8BitGray7, kRGB8BitGray7, kRGB8BitGray7 );
  3016.         SetIfColor ( color );
  3017.         this->BotRightSide ( controlArea );
  3018.         
  3019.         //    • Inset our rectangle as we move to the next level
  3020.         InsetRect ( controlArea, 1, 1 );
  3021.         
  3022.         //    • Light on edge of button - light source edge
  3023.         SetIfColor ( gRGBWhite );
  3024.         this->TopLeftSide ( controlArea );
  3025.  
  3026.         //    • Inside edge of bottom right shadow
  3027.         color = kMediumGray;
  3028.         SetIfColor ( color );
  3029.         this->BotRightSide ( controlArea );    
  3030.         
  3031.         //    •• Now draw the corners 
  3032.         //    •    TopLeft 1
  3033.         this->TopLeftCorner ( insetArea, gRGBWhite, gRGBWhite );
  3034.         
  3035.         //    • TopRight 2
  3036.         SetRGBColor ( light, kRGB8BitGray3, kRGB8BitGray3, kRGB8BitGray3 );
  3037.         this->TopRightCorner ( insetArea, light, light );
  3038.         
  3039.         //    • BotLeft 3
  3040.         //    • Colors same as previous corner
  3041.         this->BotLeftCorner ( insetArea, light, light );
  3042.         
  3043.         //    • BotRight 4
  3044.         SetRGBColor ( light, kRGB8BitGray8, kRGB8BitGray8, kRGB8BitGray8 );
  3045.         SetRGBColor ( dark, kRGB8BitGray9, kRGB8BitGray9, kRGB8BitGray9 );
  3046.         this->BotRightCorner ( insetArea, light, dark, hilite );
  3047.         
  3048.         //    • Setup fill color for button face
  3049.         color = kLightGray2;
  3050.         
  3051.     }
  3052.     
  3053.     //    • Inset our rectangle so that we can fill the rest of the area
  3054.     InsetRect ( controlArea, 1, 1 );
  3055.  
  3056.     //    • Now we will fill the rest of the button NOTE: color was setup at the
  3057.     //    end of either the hilite or normal draw routines
  3058.     SetIfColor ( color );
  3059.     PaintRect ( controlArea );
  3060.     
  3061. } // T3DIconAdorner::Draw8Bit
  3062.  
  3063.  
  3064. //-------------------------------------------------------------------------------------
  3065. // T3DIconAdorner::Draw4Bit
  3066. //-------------------------------------------------------------------------------------
  3067. #pragma segment A3DControlRes
  3068.  
  3069. pascal void T3DIconAdorner::Draw4Bit ( const CRect& rect,
  3070.                                                     Boolean hilite )
  3071. {
  3072.     CRect             insetArea;
  3073.     CRect             controlArea;
  3074.     CRGBColor         color;
  3075.     CRGBColor         light;
  3076.     CRGBColor         dark;
  3077.  
  3078.     //    • Make a copy of the rect passed in
  3079.     controlArea = rect;
  3080.     
  3081.     //    • Save off the area passed in
  3082.     insetArea = rect;
  3083.  
  3084.     //    • Draw the hilited button
  3085.     if ( hilite ) 
  3086.     {    
  3087.  
  3088.         //    • Outside edge of left top shadow
  3089.         SetRGBColor ( color, kRGB4BitGray3, kRGB4BitGray3, kRGB4BitGray3 );
  3090.         SetIfColor ( color );
  3091.         this->TopLeftSide ( controlArea );
  3092.  
  3093.         //    • Outside edge of bottom right shadow
  3094.         SetRGBColor ( color, kRGB4BitGray1, kRGB4BitGray1, kRGB4BitGray1 );
  3095.         SetIfColor ( color );
  3096.         this->BotRightSide ( controlArea );
  3097.         
  3098.         //    • Inset our rectangle as we move to the next level
  3099.         InsetRect ( controlArea, 1, 1 );
  3100.         
  3101.         //    • Inside edge of left top shadow
  3102.         SetRGBColor ( color, kRGB4BitGray3, kRGB4BitGray3, kRGB4BitGray3 );
  3103.         SetIfColor ( color );
  3104.         this->TopLeftSide ( controlArea );
  3105.  
  3106.         //    • Inside edge of bottom right shadow
  3107.         SetRGBColor ( color, kRGB4BitGray1, kRGB4BitGray1, kRGB4BitGray1 );
  3108.         SetIfColor ( color );
  3109.         this->BotRightSide ( controlArea );    
  3110.         
  3111.         //    •• Now draw the corners
  3112.         //    •    TopLeft 1
  3113.         SetRGBColor ( light, kRGB4BitGray3, kRGB4BitGray3, kRGB4BitGray3 );
  3114.         this->TopLeftCorner ( insetArea, light, light );
  3115.         
  3116.         //    • TopRight 2
  3117.         SetRGBColor ( light, kRGB4BitGray2, kRGB4BitGray2, kRGB4BitGray2 );
  3118.         this->TopRightCorner ( insetArea, light, light );
  3119.         
  3120.         //    • BotLeft 3
  3121.         SetRGBColor ( light, kRGB4BitGray2, kRGB4BitGray2, kRGB4BitGray2 );
  3122.         this->BotLeftCorner ( insetArea, light, light );
  3123.         
  3124.         //    • BotRight 4
  3125.         SetRGBColor ( light, kRGB4BitGray1, kRGB4BitGray1, kRGB4BitGray1 );
  3126.         this->BotRightCorner ( insetArea, light, light, hilite );
  3127.         
  3128.         //    • Setup fill color for button face - hilite
  3129.         SetRGBColor ( color, kRGB4BitGray2, kRGB4BitGray2, kRGB4BitGray2 );
  3130.         
  3131.     }
  3132.     else //    • Draw the unhilited button
  3133.     {
  3134.         //    • Outside edge of left top shadow
  3135.         SetRGBColor ( color, kRGB4BitGray1, kRGB4BitGray1, kRGB4BitGray1 );
  3136.         SetIfColor ( color );
  3137.         this->TopLeftSide ( controlArea );
  3138.  
  3139.         //    • Outside edge of bottom right shadow
  3140.         SetRGBColor ( color, kRGB4BitGray2, kRGB4BitGray2, kRGB4BitGray2 );
  3141.         SetIfColor ( color );
  3142.         this->BotRightSide ( controlArea );
  3143.         
  3144.         //    • Inset our rectangle as we move to the next level
  3145.         InsetRect ( controlArea, 1, 1 );
  3146.         
  3147.         //    • Light on edge of button - light source edge
  3148.         SetIfColor ( gRGBWhite );
  3149.         this->TopLeftSide ( controlArea );
  3150.  
  3151.         //    • Inside edge of bottom right shadow
  3152.         SetRGBColor ( color, kRGB4BitGray2, kRGB4BitGray2, kRGB4BitGray2 );
  3153.         SetIfColor ( color );
  3154.         this->BotRightSide ( controlArea );    
  3155.         
  3156.         //    •• Now draw the corners
  3157.         //    •    TopLeft 1
  3158.         this->TopLeftCorner ( insetArea, gRGBWhite, gRGBWhite );
  3159.         
  3160.         //    • TopRight 2
  3161.         SetRGBColor ( light, kRGB4BitGray1, kRGB4BitGray1, kRGB4BitGray1 );
  3162.         this->TopRightCorner ( insetArea, light, light );
  3163.         
  3164.         //    • BotLeft 3
  3165.         //    • Colors same as previous corner
  3166.         this->BotLeftCorner ( insetArea, light, light );
  3167.         
  3168.         //    • BotRight 4
  3169.         SetRGBColor ( light, kRGB4BitGray3, kRGB4BitGray3, kRGB4BitGray3 );
  3170.         this->BotRightCorner ( insetArea, light, light, hilite );
  3171.         
  3172.         //    • Setup fill color for button face
  3173.         SetRGBColor ( color, kRGB4BitGray1, kRGB4BitGray1, kRGB4BitGray1 );
  3174.         
  3175.     }
  3176.     
  3177.     //    • Inset our rectangle so that we can fill the rest of the area
  3178.     InsetRect ( controlArea, 1, 1 );
  3179.  
  3180.     //    • Now we will fill the rest of the button NOTE: color was setup at the
  3181.     //    end of either the hilite or normal draw routines
  3182.     SetIfColor ( color );
  3183.     PaintRect ( controlArea );
  3184.     
  3185. } // T3DIconAdorner::Draw4Bit
  3186.  
  3187. //-------------------------------------------------------------------------------------
  3188. // T3DIconAdorner::Draw1Bit
  3189. //-------------------------------------------------------------------------------------
  3190. #pragma segment A3DControlRes
  3191.  
  3192. pascal void T3DIconAdorner::Draw1Bit ( const CRect& rect,
  3193.                                                     Boolean hilite )
  3194. {
  3195.     CRect insetArea;
  3196.     CRect controlArea;
  3197.  
  3198.     CPenNormal();
  3199.     
  3200.     //    • Make a copy of the rect passed in
  3201.     controlArea = rect;
  3202.     
  3203.     //    • Save off the area passed in
  3204.     insetArea = controlArea;
  3205.  
  3206.     //    • First we paint the inside white
  3207.     PenPat(&qd.white);
  3208.     ForeColor ( whiteColor );
  3209.     PaintRect ( controlArea );
  3210.     
  3211.     //    • Outside edge of bottom right shadow
  3212.     PenPat ( &qd.gray );
  3213.     ForeColor ( blackColor );
  3214.     this->BotRightSide ( controlArea );
  3215.     
  3216.     //    • Inset the rectangle again for the next level
  3217.     InsetRect ( controlArea, 1, 1 );
  3218.     
  3219.     //    • Inside edge of bottom right shadow
  3220.     this->BotRightSide ( controlArea );
  3221.  
  3222.     //    • We are hiliting so we need to invert the whole thing
  3223.     if  ( hilite ) 
  3224.         InvertRect ( insetArea );
  3225.  
  3226. } // T3DIconAdorner::Draw1Bit
  3227.  
  3228.  
  3229. //=====================================================================================
  3230. // •• BUTTON FRAME
  3231. //-------------------------------------------------------------------------------------
  3232. // T3DIconAdorner::Frame
  3233. //-------------------------------------------------------------------------------------
  3234. #pragma segment A3DControlRes
  3235.  
  3236. pascal void T3DIconAdorner::Frame ( const CRect& rect )
  3237. {
  3238.     //    •    Draw the frame around the button this never changes
  3239.     MoveTo ( rect.left, rect.bottom - 2 );
  3240.     LineTo ( rect.left, rect.top + 1 );
  3241.     MoveTo ( rect.left + 1, rect.top );
  3242.     LineTo ( rect.right - 2, rect.top );
  3243.     MoveTo ( rect.left + 1, rect.bottom - 1 );
  3244.     LineTo ( rect.right - 2, rect.bottom - 1 );
  3245.     MoveTo ( rect.right - 1, rect.bottom - 2 );
  3246.     LineTo ( rect.right - 1, rect.top + 1 );
  3247.  
  3248. } // T3DIconAdorner::Frame
  3249.  
  3250. //=====================================================================================
  3251. // •• EDGE DRAWING
  3252. //-------------------------------------------------------------------------------------
  3253. // T3DIconAdorner::TopLeftSide
  3254. //-------------------------------------------------------------------------------------
  3255. #pragma segment A3DControlRes
  3256.  
  3257. pascal void T3DIconAdorner::TopLeftSide ( const CRect& rect )
  3258. {
  3259.  
  3260.     MoveTo ( rect.left,rect.bottom-2 );
  3261.     LineTo ( rect.left,rect.top );
  3262.     LineTo ( rect.right-2,rect.top );
  3263.  
  3264. } // T3DIconAdorner::TopLeftSide
  3265.  
  3266. //-------------------------------------------------------------------------------------
  3267. // T3DIconAdorner::BotRightSide
  3268. //-------------------------------------------------------------------------------------
  3269. #pragma segment A3DControlRes
  3270.  
  3271. pascal void T3DIconAdorner::BotRightSide ( const CRect& rect )
  3272. {
  3273.  
  3274.     MoveTo ( rect.left,rect.bottom-1 );
  3275.     LineTo ( rect.right-1,rect.bottom-1 );
  3276.     LineTo ( rect.right-1,rect.top );
  3277.  
  3278. } // T3DIconAdorner::BotRightSide
  3279.  
  3280.  
  3281. //=====================================================================================
  3282. // •• CORNER DRAWING
  3283. //-------------------------------------------------------------------------------------
  3284. // T3DIconAdorner::TopLeftCorner
  3285. //-------------------------------------------------------------------------------------
  3286. #pragma segment A3DControlRes
  3287.  
  3288. pascal void T3DIconAdorner::TopLeftCorner (     const CRect& rect,
  3289.                                                             const CRGBColor light,
  3290.                                                             const CRGBColor dark  )
  3291. {
  3292.     //    • Set the outer corner pixel
  3293.     SetIfColor(dark);
  3294.     MoveTo(rect.left, rect.top);
  3295.     LineTo(rect.left, rect.top);
  3296.     
  3297.     //    • Set the inner corner pixel
  3298.     SetIfColor(light);
  3299.     MoveTo(rect.left + 1, rect.top + 1);
  3300.     LineTo(rect.left + 1, rect.top + 1);
  3301.     
  3302. } // T3DIconAdorner::TopLeftCorner
  3303.  
  3304. //-------------------------------------------------------------------------------------
  3305. // T3DIconAdorner::TopRightCorner
  3306. //-------------------------------------------------------------------------------------
  3307. #pragma segment A3DControlRes
  3308.  
  3309. pascal void T3DIconAdorner::TopRightCorner ( const CRect& rect,
  3310.                                                             const CRGBColor light,
  3311.                                                             const CRGBColor dark  )
  3312. {
  3313.     //    • Set the outer corner pixel
  3314.     SetIfColor(light);
  3315.     MoveTo(rect.right - 1, rect.top);
  3316.     LineTo(rect.right - 1, rect.top);
  3317.     
  3318.     //    • Set the inner corner pixel
  3319.     SetIfColor(dark);
  3320.     MoveTo(rect.right - 2, rect.top + 1);
  3321.     LineTo(rect.right - 2, rect.top + 1);
  3322.     
  3323. } // T3DIconAdorner::TopRightCorner
  3324.  
  3325. //-------------------------------------------------------------------------------------
  3326. // T3DIconAdorner::BotLeftCorner
  3327. //-------------------------------------------------------------------------------------
  3328. #pragma segment A3DControlRes
  3329.  
  3330. pascal void T3DIconAdorner::BotLeftCorner (     const CRect& rect,
  3331.                                                             const CRGBColor light,
  3332.                                                             const CRGBColor dark  )
  3333. {
  3334.     //    • Set the outer corner pixel
  3335.     SetIfColor(light);
  3336.     MoveTo(rect.left, rect.bottom - 1);
  3337.     LineTo(rect.left, rect.bottom - 1);
  3338.     
  3339.     //    • Set the inner corner pixel
  3340.     SetIfColor(dark);
  3341.     MoveTo(rect.left + 1, rect.bottom - 2);
  3342.     LineTo(rect.left + 1, rect.bottom - 2);
  3343.     
  3344. } // T3DIconAdorner::BotLeftCorner
  3345.  
  3346. //-------------------------------------------------------------------------------------
  3347. // T3DIconAdorner::BotRightCorner
  3348. //-------------------------------------------------------------------------------------
  3349. #pragma segment A3DControlRes
  3350.  
  3351. pascal void T3DIconAdorner::BotRightCorner ( const CRect& rect,
  3352.                                                             const CRGBColor light,
  3353.                                                             const CRGBColor dark,
  3354.                                                             Boolean hilite )
  3355. {
  3356.     if ( hilite )
  3357.     {
  3358.         //    • Set the outer corner pixel
  3359.         SetIfColor(light);
  3360.         MoveTo(rect.right - 1, rect.bottom - 1);
  3361.         LineTo(rect.right - 1, rect.bottom - 1);
  3362.         
  3363.         //    • Set the inner corner pixel
  3364.         SetIfColor(dark);
  3365.         MoveTo(rect.right - 2, rect.bottom - 2);
  3366.         LineTo(rect.right - 2, rect.bottom - 2);
  3367.     }
  3368.     else
  3369.     {
  3370.         //    • Set the outer corner pixel
  3371.         SetIfColor(dark);
  3372.         MoveTo(rect.right - 1, rect.bottom - 1);
  3373.         LineTo(rect.right - 1, rect.bottom - 1);
  3374.         
  3375.         //    • Set the inner corner pixel
  3376.         SetIfColor(light);
  3377.         MoveTo(rect.right - 2, rect.bottom - 2);
  3378.         LineTo(rect.right - 2, rect.bottom - 2);
  3379.     }
  3380.     
  3381. } // T3DIconAdorner::BotRightCorner
  3382.  
  3383.  
  3384. //=====================================================================================
  3385. // CLASS:    TIconSuite
  3386. //        The T3DIconButton class is based from this one.  However, you can use this
  3387. //        class alone if you wish.  It will draw an icon suite and allow you to
  3388. //        apply standard masks to respond to events
  3389. //=====================================================================================
  3390.  
  3391. //=====================================================================================
  3392. // •• INITIALIZATION & DISPOSAL
  3393. //-------------------------------------------------------------------------------------
  3394. // TIconSuite::Initialize
  3395. //-------------------------------------------------------------------------------------
  3396. #pragma segment    A3DControlOpen
  3397.  
  3398. pascal void TIconSuite::Initialize ()    // OVERRIDE
  3399. {
  3400.     inherited::Initialize ();
  3401.     
  3402.     fIconSuiteRsrcID = kNoResource;
  3403.     fAlignment = atNone;
  3404.     fDataHandle = NULL;
  3405.     fSelectorValue  = svAllAvailableData;
  3406.     
  3407. }    // TIconSuite::Initialize
  3408.  
  3409. //-------------------------------------------------------------------------------------
  3410. // TIconSuite::IIconSuite
  3411. //-------------------------------------------------------------------------------------
  3412. #pragma segment    A3DControlOpen
  3413.  
  3414. pascal void TIconSuite::IIconSuite (    TView* itsSuperView,
  3415.                                                     const VPoint& itsLocation,
  3416.                                                     const VPoint& itsSize,
  3417.                                                     SizeDeterminer itsHSizeDet,
  3418.                                                     SizeDeterminer itsVSizeDet,
  3419.                                                     ResNumber itsRsrcID,
  3420.                                                     IconAlignmentType    alignment,
  3421.                                                     IconSelectorValue selectorValue)
  3422. {
  3423.     FailInfo fi;
  3424.  
  3425.     this->IControl ( itsSuperView, itsLocation, itsSize, itsHSizeDet, itsVSizeDet );
  3426.     
  3427.     // • Setup our fields
  3428.     fAlignment = alignment;
  3429.     fEventNumber = mIconSuiteHit;                // We will use the mIconSuiteHit constant
  3430.  
  3431.     // • Installs the icon suite
  3432.     this->SetIconSuiteRsrcID ( itsRsrcID,selectorValue,kDontRedraw );
  3433.         
  3434.     // • Default is to enable hit testing
  3435.     this->SetEnable ( TRUE );                        
  3436.     
  3437. }    // TIconSuite::IIconSuite
  3438.  
  3439.  
  3440. //-------------------------------------------------------------------------------------
  3441. // TIconSuite::DoPostCreate
  3442. //-------------------------------------------------------------------------------------
  3443. #pragma segment    A3DControlOpen
  3444.  
  3445. pascal void TIconSuite::DoPostCreate(TDocument *itsDocument)
  3446. {
  3447.     inherited::DoPostCreate(itsDocument);
  3448.     
  3449.     fEventNumber = mIconSuiteHit;                // We will use the mIconSuiteHit constant
  3450.     fAlignment = atNone;
  3451.     
  3452.     // • Installs the icon suite - use the fUserArea field of the View resource
  3453.     //        as the icon suite
  3454.     this->SetIconSuiteRsrcID((short) fUserArea,svAllAvailableData,kDontRedraw);
  3455.         
  3456.     // • Default is to enable hit testing
  3457.     this->SetEnable ( TRUE );    
  3458. }
  3459.  
  3460.  
  3461. //-------------------------------------------------------------------------------------
  3462. // TIconSuite::Clone
  3463. //-------------------------------------------------------------------------------------
  3464. #pragma segment A3DControlNonRes
  3465.  
  3466. pascal TObject* TIconSuite::Clone ()    // OVERRIDE 
  3467. {
  3468.     TIconSuite* aClonedIconSuite;
  3469.     Handle itsRsrcHandle;
  3470.  
  3471.  
  3472.     // • First call inherited clone and coerce the result to our type
  3473.     aClonedIconSuite = ( TIconSuite* )( inherited::Clone ());
  3474.     
  3475.     // • Setup the cloned icon suite's fields
  3476.     aClonedIconSuite->fDataHandle = NULL;
  3477.     aClonedIconSuite->fAlignment = fAlignment;
  3478.     
  3479.     // • Now get a new copy of the resource handle and place it in the data field
  3480.     if ( fDataHandle )
  3481.     {
  3482.         // • Make the resource non-purgeable, so the Toolbox doesn't die 
  3483.         GetIconSuite ( &itsRsrcHandle, fIconSuiteRsrcID, fSelectorValue );
  3484.         
  3485.         aClonedIconSuite->fDataHandle = itsRsrcHandle;
  3486.         
  3487.         // • Check to see if it is a NIL resource
  3488.         FailNILResource ( aClonedIconSuite->fDataHandle );
  3489.             
  3490.     }
  3491.     
  3492.     // • Return the cloned icon suite
  3493.     return aClonedIconSuite;
  3494.     
  3495. }    //    TIconSuite::Clone
  3496.  
  3497. //-------------------------------------------------------------------------------------
  3498. // TIconSuite::Free
  3499. //-------------------------------------------------------------------------------------
  3500. #pragma segment A3DControlClose
  3501.  
  3502. pascal void TIconSuite::Free ()    // OVERRIDE 
  3503. {
  3504.  
  3505.     // • Get rid of the icon suite
  3506.     this->ReleaseIconSuite ();
  3507.  
  3508.     inherited::Free ();
  3509.  
  3510. }    // TIconSuite::Free
  3511.  
  3512.  
  3513. //-------------------------------------------------------------------------------------
  3514. // TIconSuite::ReleaseIconSuite
  3515. //-------------------------------------------------------------------------------------
  3516. #pragma segment A3DControlNonRes
  3517.  
  3518. pascal void TIconSuite::ReleaseIconSuite ()
  3519. {
  3520.     // • Set the rsrc ID field to nothing
  3521.     fIconSuiteRsrcID = kNoResource;
  3522.     
  3523.     // • If there is a data handle then dispose of the icon suite
  3524.     if ( fDataHandle )
  3525.     {
  3526.         OSErr    anError;
  3527.         
  3528.         anError = DisposeIconSuite ( fDataHandle, TRUE );
  3529.         fDataHandle = NULL;
  3530.     }
  3531.     
  3532. }    // TIconSuite::ReleaseIconSuite
  3533.  
  3534.  
  3535. //=====================================================================================
  3536. // •• ACCESSORS
  3537. //-------------------------------------------------------------------------------------
  3538. // TIconSuite::GetIconRect
  3539. //-------------------------------------------------------------------------------------
  3540. #pragma segment A3DControlRes
  3541.  
  3542. pascal void TIconSuite::GetIconRect ( VRect& theRect )
  3543. {
  3544.  
  3545.     this->ControlArea ( theRect );
  3546.     
  3547. }    // <- GetIconRect
  3548.  
  3549.  
  3550. //-------------------------------------------------------------------------------------
  3551. // TIconSuite::SetIconSuite
  3552. //-------------------------------------------------------------------------------------
  3553. #pragma segment A3DControlNonRes
  3554.  
  3555. pascal void TIconSuite::SetIconSuite ( Handle theSuite, Boolean redraw )
  3556. {
  3557.     ResNumber     theID;
  3558.     ResType         theType;
  3559.     CStr255         name;
  3560.  
  3561.     // • Release the existing icon suite and set the data field to
  3562.     // the new icon suite
  3563.     this->ReleaseIconSuite();
  3564.     fDataHandle = theSuite;
  3565.  
  3566.     // • Get the rsrc ID from the icon suite's handle 
  3567.     GetResInfo ( theSuite, theID, theType, name) ;
  3568.     if ( ResError() == noErr )
  3569.         fIconSuiteRsrcID = theID;
  3570.  
  3571.     // • Get everything redrawn so that the new icon can be displayed, if needed
  3572.     if ( redraw )
  3573.         this->ForceRedraw ();
  3574.         
  3575. }    // TIconSuite::SetIconSuite
  3576.  
  3577.  
  3578. //-------------------------------------------------------------------------------------
  3579. // TIconSuite::SetIconSuiteRsrcID
  3580. //-------------------------------------------------------------------------------------
  3581. #pragma segment A3DControlNonRes
  3582.  
  3583. pascal void TIconSuite::SetIconSuiteRsrcID ( short itsRsrcID, IconSelectorValue selectorValue, Boolean redraw )
  3584. {
  3585.     FailInfo     fi;
  3586.     Handle         itsRsrcHandle;
  3587.  
  3588.     if ( itsRsrcID != kNoResource )
  3589.     {    
  3590.         if (fi.Try())
  3591.         {
  3592.             // • Make the resource non-purgeable, so the Toolbox doesn't die 
  3593.             GetIconSuite ( &itsRsrcHandle, itsRsrcID, fSelectorValue );
  3594.             
  3595.             // • Check to see if it is a NIL resource
  3596.             FailNILResource ( itsRsrcHandle );
  3597.             
  3598.             // • Release the existing icon suite
  3599.             this->ReleaseIconSuite();
  3600.             
  3601.             // • Place the resource handle in our data field
  3602.             fDataHandle = itsRsrcHandle;
  3603.             fIconSuiteRsrcID = itsRsrcID;
  3604.             fSelectorValue = selectorValue;
  3605.             
  3606.             // • Hey! everything worked fine, we're out of here!!
  3607.             fi.Success ();
  3608.         }
  3609.         else    // Recover
  3610.         {
  3611.             fi.ReSignal ();
  3612.         }
  3613.  
  3614.     // • Get everything redrawn so that the new icon can be displayed, if needed
  3615.         if ( redraw )
  3616.             this->ForceRedraw ();
  3617.     
  3618.     }
  3619.         
  3620. }    // TIconSuite::SetIconSuiteRsrcID
  3621.  
  3622.  
  3623. //-------------------------------------------------------------------------------------
  3624. // TIconSuite::SetAlignment
  3625. //-------------------------------------------------------------------------------------
  3626. #pragma segment A3DControlNonRes
  3627.  
  3628. pascal void TIconSuite::SetAlignment ( IconAlignmentType newAlignment, Boolean redraw )
  3629. {
  3630.     // • Setup the field to the new alignment value
  3631.     fAlignment = newAlignment;
  3632.  
  3633.     // • Get everything redrawn so that the new icon can be displayed, if needed
  3634.     if ( redraw )
  3635.         this->ForceRedraw ();
  3636.         
  3637. }    // TIconSuite::SetAlignment
  3638.  
  3639.  
  3640. //=====================================================================================
  3641. // •• DRAWING
  3642. //-------------------------------------------------------------------------------------
  3643. // TIconSuite::Draw
  3644. //-------------------------------------------------------------------------------------
  3645. #pragma segment A3DControlRes
  3646.  
  3647. pascal void TIconSuite::Draw ( const VRect& area )    // OVERRIDE 
  3648. {
  3649.     // • Get the icon plotted with the "ttNone" transorm applied
  3650.     // this transform shows the icon in its normal state
  3651.     this->DoPlotIconSuite ( ttNone );
  3652.     
  3653.     inherited::Draw ( area );
  3654.  
  3655. }    // <- Draw
  3656.  
  3657.  
  3658. //-------------------------------------------------------------------------------------
  3659. // TIconSuite::DoPlotIconSuite    PRIVATE
  3660. //-------------------------------------------------------------------------------------
  3661. #pragma segment A3DControlRes
  3662.  
  3663. pascal void TIconSuite::DoPlotIconSuite ( IconTransformType transform )        // OVERRIDE 
  3664. {
  3665.     SignedByte oldState;
  3666.     VRect theRect;
  3667.     CRect theQDRect;
  3668.  
  3669.     // • We will only do something if we have a datahandle
  3670.     if ( fDataHandle )
  3671.     {
  3672.         // • If the data handle we have is a resource then make sure its loaded
  3673.         if ( IsAResource ( fDataHandle ))
  3674.             LoadResource ( fDataHandle );
  3675.             
  3676.         if ( *fDataHandle )                // If there's room for the icon… 
  3677.         {
  3678.             PenNormal();                        // NECESSARY? 
  3679.                     
  3680.             // • Get a Quickdraw rectangle of the control's extent
  3681.             this->GetIconRect ( theRect );
  3682.             this->ViewToQDRect ( theRect, theQDRect );
  3683.             
  3684.             // • Save off the state of the data handle
  3685.             oldState = HGetState ( fDataHandle );
  3686.             HNoPurge ( fDataHandle );
  3687.             HLock ( fDataHandle );
  3688.  
  3689.             // • Get the icon plotted using the transform passed in as
  3690.             // well as the current alignment
  3691.             PlotIconSuite ( &theQDRect, fAlignment, transform, fDataHandle);
  3692.  
  3693.             // • Restore the dtata handle's state
  3694.             HSetState ( fDataHandle, oldState );
  3695.         }
  3696.     }
  3697.     
  3698. }    // TIconSuite::DoPlotIconSuite
  3699.  
  3700.  
  3701. //=====================================================================================
  3702. // •• STATE
  3703. //-------------------------------------------------------------------------------------
  3704. // TIconSuite::Dim
  3705. //-------------------------------------------------------------------------------------
  3706. #pragma segment A3DControlRes
  3707.  
  3708. pascal void TIconSuite::Dim ()        // OVERRIDE 
  3709. {
  3710.  
  3711.     // • Plot the icon disabled if we are dimmed
  3712.     this->DoPlotIconSuite ( ttDisabled );
  3713.     
  3714. }    // TIconSuite::Dim
  3715.  
  3716.  
  3717. //-------------------------------------------------------------------------------------
  3718. // TIconSuite::Hilite
  3719. //-------------------------------------------------------------------------------------
  3720. #pragma segment A3DControlRes
  3721.  
  3722. pascal void TIconSuite::Hilite ()    // OVERRIDE
  3723. {
  3724.  
  3725.     // • If the icon is hilited then plot it "selected" otherwise plot is as 
  3726.     // normal in its unselected state
  3727.     if ( fHilite )
  3728.         this->DoPlotIconSuite ( ttSelected );
  3729.     else
  3730.         this->DoPlotIconSuite ( ttNone );
  3731.         
  3732. }    // TIconSuite::Hilite
  3733.  
  3734.  
  3735. //=====================================================================================
  3736. // CLASS:    T3DIconButton
  3737. //=====================================================================================
  3738.  
  3739. const    short    kDefaultSize    = 32;
  3740. //-------------------------------------------------------------------------------------
  3741. // T3DIconButton::Initialize
  3742. //-------------------------------------------------------------------------------------
  3743. #pragma segment A3DControlOpen
  3744.  
  3745. pascal void T3DIconButton::Initialize ()                // Override 
  3746. {
  3747.  
  3748.     inherited::Initialize ();
  3749.     
  3750.     f3DIconAdorner = NULL;
  3751.     fIconSize = kDefaultSize;        // Use 32x32 icons by default
  3752.     fMode = kButtonMode;            // Use button mode by default
  3753.     fState = FALSE;
  3754.     
  3755. } // T3DIconButton::Initialize
  3756.  
  3757. //-------------------------------------------------------------------------------------
  3758. // T3DIconButton::I3DButton
  3759. //-------------------------------------------------------------------------------------
  3760. #pragma segment A3DControlOpen
  3761.  
  3762. pascal void     T3DIconButton::I3DIconButton (    TView* itsSuperView,
  3763.                                                                         const VPoint& itsLocation,
  3764.                                                                         const VPoint& itsSize,
  3765.                                                                         SizeDeterminer itsHSizeDet,
  3766.                                                                         SizeDeterminer itsVSizeDet,
  3767.                                                                         short iconSize,
  3768.                                                                         ResNumber itsRsrcID,
  3769.                                                                         ButtonMode mode,
  3770.                                                                         Boolean state )
  3771. {
  3772.  
  3773.     IconSelectorValue selectorValue;
  3774.     
  3775.     switch ( iconSize ) 
  3776.     {
  3777.         case 12:
  3778.                 selectorValue = svAllMiniData;
  3779.             break;
  3780.         case 16:
  3781.                 selectorValue = svAllSmallData;
  3782.             break;
  3783.         case 32:
  3784.                 selectorValue = svAllLargeData;
  3785.             break;
  3786.     }
  3787.     
  3788.     //    • Get our superclass setup
  3789.     this->IIconSuite ( itsSuperView, itsLocation, itsSize,
  3790.                                         itsHSizeDet, itsVSizeDet,
  3791.                                             itsRsrcID, atAbsoluteCenter, selectorValue );
  3792.     
  3793.     fIconSize  = iconSize;
  3794.     this->SetMode ( mode );
  3795.     fState = state;
  3796.     fEventNumber = mIconButtonHit;
  3797.     
  3798.     //    • Get the correct hiliteState setup
  3799.     if ( fState )
  3800.         this->HiliteState ( fState, kRedraw );
  3801.     
  3802.     //    • If we are being built procedurally then build the adorner
  3803.     if ( f3DIconAdorner == NULL )
  3804.         this->CreateButtonAdorner ();
  3805.     
  3806. } // T3DIconButton::I3DButton
  3807.  
  3808. //-------------------------------------------------------------------------------------
  3809. // T3DIconButton::DoPostCreate
  3810. //-------------------------------------------------------------------------------------
  3811. #pragma segment A3DControlOpen
  3812.  
  3813. pascal void T3DIconButton::DoPostCreate ( TDocument *itsDocument ) // Override 
  3814. {
  3815.  
  3816.     inherited::DoPostCreate ( itsDocument );
  3817.  
  3818.     fEventNumber = mIconButtonHit;
  3819.     
  3820.     if ( f3DIconAdorner == NULL )
  3821.         this->CreateButtonAdorner ();
  3822.  
  3823. } // T3DIconButton::DoPostCreate
  3824.  
  3825. //-------------------------------------------------------------------------------------
  3826. // T3DIconButton::CreateButtonAdorner
  3827. //-------------------------------------------------------------------------------------
  3828. #pragma segment A3DControlOpen
  3829.  
  3830. pascal void T3DIconButton::CreateButtonAdorner ()
  3831. {
  3832.     
  3833.     // •    Add the 3D Button Adorner
  3834.     T3DIconAdorner* adorner = new T3DIconAdorner;
  3835.     adorner->I3DIconAdorner ( kFreeOnDeletion );
  3836.     f3DIconAdorner = adorner;
  3837.     this->AddAdorner ( adorner, kAdornFirst, kDontInvalidate );
  3838.  
  3839. } // T3DIconButton::CreateButtonAdorner
  3840.  
  3841. //-------------------------------------------------------------------------------------
  3842. // T3DIconButton::GetIconRect
  3843. //-------------------------------------------------------------------------------------
  3844. #pragma segment A3DControlRes
  3845.  
  3846. pascal void T3DIconButton::GetIconRect ( VRect& theRect )
  3847. {
  3848.  
  3849.     this->ControlArea ( theRect );
  3850.     
  3851.     VCoordinate iconSize = this->GetIconSize ( theRect.GetSize () );
  3852.     
  3853. //    Center the icon
  3854.     theRect.top += ( theRect.bottom - theRect.top - iconSize ) / 2;
  3855.     theRect.bottom = theRect.top + iconSize;
  3856.     theRect.left += ( theRect.right - theRect.left - iconSize ) / 2;
  3857.     theRect.right = theRect.left + iconSize;
  3858.  
  3859. }    //    T3DIconButton::GetIconRect
  3860.  
  3861. //-------------------------------------------------------------------------------------
  3862. // T3DIconButton::GetIconSize
  3863. //-------------------------------------------------------------------------------------
  3864. #pragma segment A3DControlNonRes
  3865.  
  3866. pascal short T3DIconButton::GetIconSize ( const VPoint& /*viewSize*/ )
  3867. {
  3868.  
  3869.     return fIconSize;
  3870.     
  3871. } // T3DIconButton::GetIconSize
  3872.  
  3873. //-------------------------------------------------------------------------------------
  3874. // T3DIconButton::Hilite
  3875. //-------------------------------------------------------------------------------------
  3876. #pragma segment A3DControlRes
  3877.  
  3878. pascal void T3DIconButton::Hilite ()        // Override
  3879. {
  3880.  
  3881.     VRect    area;
  3882.     this->GetExtent ( area) ;
  3883.     f3DIconAdorner->Draw ( this, area );
  3884.     
  3885.     inherited::Hilite ();
  3886.  
  3887. } // T3DIconButton::Hilite
  3888.  
  3889.  
  3890. //-------------------------------------------------------------------------------------
  3891. // T3DIconButton::Dim
  3892. //-------------------------------------------------------------------------------------
  3893. #pragma segment A3DControlRes
  3894.  
  3895. pascal void T3DIconButton::Dim ()        // Override
  3896. {
  3897.     inherited::Dim ();
  3898.  
  3899. } // T3DIconButton::Dim
  3900.  
  3901. //-------------------------------------------------------------------------------------
  3902. // T3DIconButton::SetIconSuite
  3903. //-------------------------------------------------------------------------------------
  3904. #pragma segment A3DControlNonRes
  3905.  
  3906. pascal void T3DIconButton::SetIconSuite ( Handle theSuite, 
  3907.                                                         Boolean redraw )
  3908. {
  3909.  
  3910.     inherited::SetIconSuite ( theSuite, redraw );
  3911.     
  3912.     this->SetAlignment ( atAbsoluteCenter, redraw );
  3913.  
  3914. } // T3DIconButton::SetIconSuite
  3915.  
  3916. //-------------------------------------------------------------------------------------
  3917. // T3DIconButton::SetIconSuiteRsrcID
  3918. //-------------------------------------------------------------------------------------
  3919. #pragma segment A3DControlNonRes
  3920.  
  3921. pascal void T3DIconButton::SetIconSuiteRsrcID ( short itsRsrcID, 
  3922.                                                                 IconSelectorValue selectorValue, 
  3923.                                                                 Boolean redraw )
  3924. {
  3925.  
  3926.     inherited::SetIconSuiteRsrcID ( itsRsrcID, selectorValue, redraw );
  3927.     this->SetAlignment ( atAbsoluteCenter,redraw );
  3928.     
  3929. } // T3DIconButton::SetIconSuiteRsrcID
  3930.  
  3931. //-------------------------------------------------------------------------------------
  3932. // T3DIconButton::SetIconRsrcID
  3933. //-------------------------------------------------------------------------------------
  3934. #pragma segment A3DControlNonRes
  3935.  
  3936. pascal void T3DIconButton::SetIconRsrcID ( short itsRsrcID, Boolean redraw )
  3937. {
  3938.  
  3939.     VRect theRect;
  3940.     IconSelectorValue selectorValue;
  3941.     
  3942.     this->ControlArea ( theRect );
  3943.     switch ( this->GetIconSize ( theRect.GetSize () ) ) 
  3944.     {
  3945.         case 12:
  3946.                 selectorValue = svAllMiniData;
  3947.             break;
  3948.         case 16:
  3949.                 selectorValue = svAllSmallData;
  3950.             break;
  3951.         case 32:
  3952.                 selectorValue = svAllLargeData;
  3953.             break;
  3954.     }
  3955.     
  3956.     this->SetIconSuiteRsrcID ( itsRsrcID, selectorValue, redraw );
  3957.  
  3958. } // T3DIconButton::SetIconRsrcID
  3959.  
  3960. //-------------------------------------------------------------------------------------
  3961. // T3DIconButton::SetMode
  3962. //-------------------------------------------------------------------------------------
  3963. #pragma    segment    A3DControlOpen
  3964.  
  3965. pascal void T3DIconButton::SetMode ( ButtonMode newMode )
  3966. {
  3967.             
  3968.     fMode = newMode;
  3969.     
  3970. }    // T3DIconButton::SetMode
  3971.  
  3972. //-------------------------------------------------------------------------------------
  3973. // T3DIconButton::GetMode
  3974. //-------------------------------------------------------------------------------------
  3975. #pragma    segment    A3DControlOpen
  3976.  
  3977. pascal ButtonMode T3DIconButton::GetMode ()
  3978. {
  3979.             
  3980.     return fMode;
  3981.     
  3982. }    // T3DIconButton::GetMode
  3983.  
  3984. //-------------------------------------------------------------------------------------
  3985. // T3DIconButton::IsSelected
  3986. //-------------------------------------------------------------------------------------
  3987. #pragma    segment    A3DControlNonRes
  3988.  
  3989. pascal Boolean T3DIconButton::IsSelected ( void )
  3990. {
  3991.             
  3992.     return fHilite;
  3993.     
  3994. }    // T3DIconButton::IsSelected
  3995.  
  3996. //-------------------------------------------------------------------------------------
  3997. // T3DIconButton::TrackMouse
  3998. //-------------------------------------------------------------------------------------
  3999. #pragma segment A3DControlSelCommand
  4000.  
  4001. pascal void T3DIconButton::TrackMouse (    TrackPhase aTrackPhase,
  4002.                                                              VPoint& ,
  4003.                                                              // anchorPoint
  4004.                                                              VPoint& ,
  4005.                                                              // previousPoint
  4006.                                                              VPoint& nextPoint,
  4007.                                                              Boolean )                            // OVERRIDE
  4008. {
  4009.     if (!this->IsDimmed())
  4010.         switch (aTrackPhase)
  4011.         {
  4012.             case trackBegin:
  4013.                 fState = fHilite;
  4014.                 this->HiliteState ( TRUE, kRedraw );
  4015.                 break;
  4016.             case trackContinue:
  4017.                 if (this->ContainsMouse ( nextPoint ))
  4018.                     this->HiliteState ( TRUE, kRedraw );
  4019.                 else
  4020.                     this->HiliteState ( fState, kRedraw);
  4021.                 break;
  4022.             case trackEnd:
  4023.                 if (this->ContainsMouse ( nextPoint ))
  4024.                 {
  4025.                     switch ( fMode )
  4026.                     {
  4027.                         case kButtonMode:
  4028.                             if ( fHilite )
  4029.                                 this->HiliteState ( FALSE, kRedraw);
  4030.                             break;
  4031.                         case kSwitchMode:
  4032.                             this->HiliteState ( !fHilite, kRedraw);
  4033.                             break;
  4034.                         case kRadioMode:
  4035.                             if ( !fHilite )
  4036.                                 this->HiliteState ( TRUE, kRedraw );
  4037.                             break;
  4038.                     }
  4039.                     
  4040.                     this->HandleEvent ( fEventNumber, this, NULL );
  4041.                 }
  4042.                 break;
  4043.         }
  4044. }    // T3DIconButton::TrackMouse
  4045.  
  4046.  
  4047.  
  4048.